I would use a combination of Arrayr.prototype.reduce
and Arrayr.prototype.some
methods with spread operator.
1. Explicit solution. Based on complete knowledge of the array object contains.
list = list.reduce((r, i) =>
!r.some(j => i.x === j.x && i.y === j.y) ? [...r, i] : r
, [])
Here we have strict limitation on compared objects structure: {x: N, y: M}
. And [{x:1, y:2}, {x:1, y:2, z:3}]
will be filtered to [{x:1, y:2}]
.
2. Generic solution, JSON.stringify()
. The compared objects could have any number of any properties.
list = list.reduce((r, i) =>
!r.some(j => JSON.stringify(i) === JSON.stringify(j)) ? [...r, i] : r
, [])
This approach has a limitation on properties order, so [{x:1, y:2}, {y:2, x:1}]
won't be filtered.
3. Generic solution, Object.keys()
. The order doesn't matter.
list = list.reduce((r, i) =>
!r.some(j => !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
This approach has another limitation: compared objects must have the same list of keys.
So [{x:1, y:2}, {x:1}]
would be filtered despite the obvious difference.
4. Generic solution, Object.keys()
+ .length
.
list = list.reduce((r, i) =>
!r.some(j => Object.keys(i).length === Object.keys(j).length
&& !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
With the last approach objects are being compared by the number of keys, by keys itself and by key values.
I created a Plunker to play with it.