I'm storing some coordinates in an array. It looks like this:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}]
How can I filter this array so the objects are unique, meaning there are no duplicates of objects with same x and y value? Expected output should be:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}]
I've seen some similar solutions, but they didn't really solve this problem. I started with the following function
const output = Object.values(
coords.reduce( (c, e) => {
if (!c[e.x]) c[e.x] = e;
return c;
}, {})
but it only returns objects with different x values, so it just completely ommits y value.
We can use Array.reduce(), along with a Map to get the required result.
We'd add each item to the map, using the concatenated x and y values as keys, then return the values() to get de-duplicated values.
This will have complexity of O(n), so it will be efficient for large arrays.
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}];
const dedup = [...coords.reduce((map, { x, y }) => {
return (map.set(`${x}-${y}`, { x, y }));
}, new Map()).values()];
console.log('De-duplicated:', dedup)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Or with a regular object:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}];
const dedup = Object.values(coords.reduce((acc, { x, y }) => {
return { ...acc, [`${x}-${y}`]: { x, y }}
}, {}));
console.log('De-duplicated:', dedup)
.as-console-wrapper { max-height: 100% !important; top: 0; }