steve-o
steve-o

Reputation: 1403

Remove duplicate elements based on date field in javascript

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"
}]

Upvotes: 0

Views: 1892

Answers (4)

Ele
Ele

Reputation: 33726

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);

Upvotes: 7

vol7ron
vol7ron

Reputation: 42099

This isn't the best answer, just another take on @Ele's solution offered for completeness. 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);

Upvotes: 0

Arman Charan
Arman Charan

Reputation: 5797

Map and Array.prototype.map() can be combined 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)

Upvotes: 1

sjb-sjb
sjb-sjb

Reputation: 1187

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.

Upvotes: 1

Related Questions