Reputation: 22804
I am trying to remove duplicate objects from an array, and keep only the objects which have the highest nb
value.
Example:
From this array:
let arr = [
{id: 1, nb: 1},
{id: 1, nb: 4},
{id: 2, nb: 1},
{id: 3, nb: 1},
{id: 1, nb: 2},
{id: 1, nb: 3},
{id: 2, nb: 7},
{id: 2, nb: 8},
];
I am supposed to get this:
arr2 = [
{ id: 1, nb: 4 },
{ id: 2, nb: 8 },
{ id: 3, nb: 1 }
]
The algorithm below is very correct in theory, however I see the original array is modified by the end (see the last console.log(arr)
below):
Code:
let arr = [
{id: 1, nb: 1},
{id: 1, nb: 4},
{id: 2, nb: 1},
{id: 3, nb: 1},
{id: 1, nb: 2},
{id: 1, nb: 3},
{id: 2, nb: 7},
{id: 2, nb: 8},
];
// Original array
console.log(arr);
let tmp = {};
for(let i=0; i<arr.length; i++) {
if( !tmp[arr[i].id] ) {
tmp[arr[i].id] = arr[i];
} else {
if (tmp[arr[i].id].nb < arr[i].nb ) {
tmp[arr[i].id].nb = arr[i].nb;
}
}
}
var result = Object.values(tmp);
// This output the desired result
console.log(result);
// Why the original array changed ?
console.log(arr);
This will output:
> Array [Object { id: 1, nb: 1 }, Object { id: 1, nb: 4 }, Object { id: 2, nb: 1 }, Object { id: 3, nb: 1 }, Object { id: 1, nb: 2 }, Object { id: 1, nb: 3 }, Object { id: 2, nb: 7 }, Object { id: 2, nb: 8 }]
> Array [Object { id: 1, nb: 4 }, Object { id: 2, nb: 8 }, Object { id: 3, nb: 1 }]
> Array [Object { id: 1, nb: 4 }, Object { id: 1, nb: 4 }, Object { id: 2, nb: 8 }, Object { id: 3, nb: 1 }, Object { id: 1, nb: 2 }, Object { id: 1, nb: 3 }, Object { id: 2, nb: 7 }, Object { id: 2, nb: 8 }]
Why did the original array changed when there is no processing on it apart from looping?
Upvotes: 0
Views: 99
Reputation: 8239
The original array is updated at last as the objects in your tmp
map and arr
share the same object reference. So changes made in tmp
will be reflected in arr
. You can use Object.assign() to make them point to separate reference. Try the following:
let arr = [ {id: 1, nb: 1}, {id: 1, nb: 4}, {id: 2, nb: 1}, {id: 3, nb: 1}, {id: 1, nb: 2}, {id: 1, nb: 3}, {id: 2, nb: 7}, {id: 2, nb: 8}, ];
let tmp = {};
for(let i=0; i<arr.length; i++) {
if( !tmp[arr[i].id] ) {
tmp[arr[i].id] = Object.assign({},arr[i]);
} else {
if (tmp[arr[i].id].nb < arr[i].nb ) {
tmp[arr[i].id].nb = arr[i].nb;
}
}
}
var result = Object.values(tmp);
console.log(result)
Upvotes: 2
Reputation: 28475
Because objects in both the arrays are sharing the same reference.
You will need to update from
tmp[arr[i].id] = arr[i];
to
tmp[arr[i].id] = JSON.parse(JSON.stringify(arr[i]));
let arr = [
{id: 1, nb: 1},
{id: 1, nb: 4},
{id: 2, nb: 1},
{id: 3, nb: 1},
{id: 1, nb: 2},
{id: 1, nb: 3},
{id: 2, nb: 7},
{id: 2, nb: 8},
];
let tmp = {};
for(let i=0; i<arr.length; i++) {
if( !tmp[arr[i].id] ) {
tmp[arr[i].id] = JSON.parse(JSON.stringify(arr[i]));
} else {
if (tmp[arr[i].id].nb < arr[i].nb ) {
tmp[arr[i].id].nb = arr[i].nb;
}
}
}
var result = Object.values(tmp);
console.log(arr); // original array unchanged
Upvotes: 1