Estoy almacenando algunas coordenadas en una matriz. Se parece a esto:
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}]¿Cómo puedo filtrar esta matriz para que los objetos sean únicos, lo que significa que no hay duplicados de objetos con el mismo valor de x e y? El resultado esperado debe ser:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}]He visto algunas soluciones similares, pero en realidad no resolvieron este problema. comencé con la siguiente función
const output = Object.values( coords.reduce( (c, e) => { if (!c[ex]) c[ex] = e; return c; }, {})pero solo devuelve objetos con diferentes valores de x, por lo que omite por completo el valor de y.
Una idea es usar un Conjunto, mapear x e y en una cadena, y luego deserializar el Conjunto para tener x, y únicos.
p.ej..
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 = [...new Set(coords.map(m => `${mx}:${my}`))].map(m => { const [x,y] = m.split(':').map(n => n | 0); return {x,y}; }); console.log(dedup);Una solución bastante ineficiente (O(n^2)), pero flexible y sencilla: primero define una función que verifica si dos coordenadas son iguales. Luego, filtra todos los elementos que tienen un elemento igual en una posición posterior en la matriz.
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 customUnique = (arr, isEqual) => { // filter elements where an equal element exists at an earlier position // thus the first element is kept return arr.filter((a, i) => !arr.some((b, j) => i > j && isEqual(a, b))) } console.log(customUnique(coords, (a, b) => ax === bx && ay === by))Puede usar originalArray.reduce() con una matriz en lugar de un objeto, por lo que puede usar array.find.
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}] console.log( coords.reduce((arr, e) => { if (!arr.find(item => item.x == ex && item.y == ey)) { arr.push(e); } return arr; }, []) );