2

I have an array of Objects with duplicates. I want to remove those duplicates but need to get the "duplicate" where a third key has the higher value.

Tried this solutions: Remove duplicates from an array of objects in JavaScript but this gives me always the first duplicate and I need to check which has the higher value of third keys.

let testArray = [
    { id: 1, value: "test1", value1: 1 },
    { id: 2, value: "test2", value1: 1 },
    { id: 1, value: "test3", value1: 5 }
];

let filtered = testArray.reduce((accumulator, current) => {
    if (!accumulator.find(({ id }) => id === current.id)) {
        accumulator.push(current);
    }
    return accumulator;
}, []);
console.log(filtered);

/* 
Result is:
[ { id: 1, value: 'test1', value1: 1 },
  { id: 2, value: 'test2', value1: 1 } ]

Result desired:
[ { id: 1, value: 'test1', value1: 5 },
  { id: 2, value: 'test2', value1: 1 } ]
*/

I expect a result like:

[ { id: 1, value: 'test1', value1: 1 },
  { id: 2, value: 'test2', value1: 5 } ]

of the testArray

  • You could sort the array before searching for duplicates. That would not be efficient, but it would work. It just depends on how many data you have. – Karl-André Gagnon Jul 22 '19 at 15:52
  • 1
    Why is `'test2'` have a value1 of `5` in the desired result but `1` in the input data? – Mark Jul 22 '19 at 15:52
  • In reducer function, you would have to add additional condition and if current element exists and has a higher value, then you would have to swap it for the current one. Otherwise, push the value if it's not there. Otherwise, do nothing. – The Witness Jul 22 '19 at 15:54
  • what about `value`? do you like to mutate the object? – Nina Scholz Jul 22 '19 at 15:56
  • @MarkMeyer yes true that was wrong. I changed the post. Thanks. – Wolfgang Terzer Jul 22 '19 at 15:57
  • @NinaScholz I need to have unique id's but where 2 id's are the same I need to grab the element where "value1" has the higher value. – Wolfgang Terzer Jul 22 '19 at 16:01

2 Answers2

2

You could search for the index and if valid check the value and update the array if the value is greater.

let testArray = [
    { id: 1, value: "test1", value1: 1 },
    { id: 2, value: "test2", value1: 1 },
    { id: 1, value: "test3", value1: 5 }
];

let filtered = testArray.reduce((accumulator, current) => {
    let index = accumulator.findIndex(({ id }) => id === current.id)
    if (index === -1) {
        accumulator.push(current);
    } else if (accumulator[index].value1 < current.value1) {
        accumulator[index] = current;
    }
    return accumulator;
}, []);

console.log(filtered);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Simply maintain a map corresponding to each id, and update the map if the existing value is less than new value, Object.values() on the map will give you the desired result:

let testArray = [ { id: 1, value: "test1", value1: 1 }, { id: 2, value: "test2", value1: 1 }, { id: 1, value: "test3", value1: 5 } ];

let filtered = Object.values(testArray.reduce((acc, curr)=>{
  acc[curr.id] = acc[curr.id] && acc[curr.id].value1 > curr.value1 ?  acc[curr.id] : curr;
  return acc;
},{}));
console.log(filtered);
amrender singh
  • 7,949
  • 3
  • 22
  • 28