admin管理员组

文章数量:1426025

I want a function that takes an array and filters out old duplicates.

Specifically, if duplicate ids exist in myList, keep only the object with the newest date. Given the following array

let myList = [{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-21 21:04:13"
},
{
    id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
    date: "2018-02-22 21:04:13"
},
{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-23 21:04:13"
}]

the function should return:

[{
    id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
    date: "2018-02-22 21:04:13"
},
{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-23 21:04:13"
}]

I want a function that takes an array and filters out old duplicates.

Specifically, if duplicate ids exist in myList, keep only the object with the newest date. Given the following array

let myList = [{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-21 21:04:13"
},
{
    id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
    date: "2018-02-22 21:04:13"
},
{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-23 21:04:13"
}]

the function should return:

[{
    id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
    date: "2018-02-22 21:04:13"
},
{
    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
    date: "2018-02-23 21:04:13"
}]
Share Improve this question asked Mar 24, 2018 at 2:01 steve-osteve-o 1,4031 gold badge15 silver badges22 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 7

You can use the function reduce to build the desired output.

let myList = [{    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",    date: "2018-02-21 21:04:13"},{    id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",    date: "2018-02-22 21:04:13"},{    id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",    date: "2018-02-23 21:04:13"}];

let result = Object.values(myList.reduce((a, {id, date}) => {
  if (a[id]) {
    if (a[id].date < date) a[id] = {id, date};
  } else a[id] = {id, date};
  
  return a;
}, {}));

console.log(result);

Put the entries into a hash table keyed by id. Each time you add an entry, look up the id and either keep the existing entry or replace it with the new one, based on whichever has a more recent date.

Map and Array.prototype.map() can be bined to functionally filter key based duplicates from arrays.

Array.prototype.sort() can be leveraged to guarantee order.

See below for a practical example.

// Input.
const input = [
  {id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-21 21:04:13"}, 
  {id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5", date: "2018-02-22 21:04:13"}, 
  {id: "e9519e95-5a10-4274-ac24-de72ad60ffd7", date: "2018-02-23 21:04:13"}
]

// Sort By Date.
const sortDate = array => array.sort((A, B) => new Date(A.date)*1 - new Date(B.date)*1)

// Filter Duplicates.
const filter = array => [...new Map(array.map(x => [x.id, x])).values()]

// Output.
const outputRaw = filter(input) // No guaranteed order.
const outputSorted = sortDate(filter(sortDate(input))) // Guaranteed latest.

// Proof.
console.log('Raw', outputRaw)
console.log('Sorted', outputSorted)

This isn't the best answer, just another take on @Ele's solution offered for pleteness. Instead of plucking the values after the unique set is found, it works on the returned array for each iteration. The find during each iteration should be less efficient than a key lookup, which is one of the reasons it's not the best answer.

let myList = [{
  id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
  date: "2018-02-21 21:04:13"
}, {
  id: "026e7ecf-d236-4aff-b26d-7546ac85b7d5",
  date: "2018-02-22 21:04:13"
}, {
  id: "e9519e95-5a10-4274-ac24-de72ad60ffd7",
  date: "2018-02-23 21:04:13"
}]

let result = myList.reduce((arr, { id, date }) => {
  let found = arr.find(v=>v.id==id)
  if (found) {
    if (found.date < date) 
      found.date = date
  } 
  else 
    arr.push({ id, date });

  return arr;
}, []);

console.log(result);

本文标签: ecmascript 6Remove duplicate elements based on date field in javascriptStack Overflow