Tengo una matriz de objetos en los que la mayoría de las propiedades pueden ser duplicados entre sí, pero un valor puede diferir:
const originalArray = [ { id: 1, name: 'x', 'description': 'x', url: 'y' }, { id: 2, name: 'x', 'description': 'x', url: 'z' } ]Quiero deduplicar esta matriz en función de una diferencia de nombre, pero conservar las diferencias de URL como una matriz en la matriz deduplicada:
const dedupedArray = [ { id: 1, name: 'x', 'description': 'x', url: ['y','z'] }, ] function removeDuplicatesByProperty(keyFn, array) { const mySet = new Set(); return array.filter(function (x) { const key = keyFn(x), isNew = !mySet.has(key); if (isNew) mySet.add(key); return isNew; }); } const dedupedArray = removeDuplicatesByProperty((x) => x.name, originalArray);Puedes usar Array.reduce :
const originalArray = [ { id: 1, name: 'x', 'description': 'x', url: 'y' }, { id: 2, name: 'x', 'description': 'x', url: 'z' } ] const res = originalArray.reduce((a,b) => { const found = a.find(e => e.name == b.name); return found ? found.url.push(b.url) : a.push({...b, url:[b.url]}), a; }, []) console.log(res)Reduzca la matriz a un Mapa y fusione los duplicados usando un mergeFn . Convierta el iterador Map.values() de nuevo en una matriz utilizando Array.from() o array spread:
const originalArray = [ { id: 1, name: 'x', 'description': 'x', url: 'y' }, { id: 2, name: 'x', 'description': 'x', url: 'z' } ] const dedupeMerge = (keyFn, mergeFn, array) => Array.from( array.reduce((acc, o) => { const key = keyFn(o); if(!acc.has(key)) return acc.set(key, o); return acc.set(key, mergeFn(acc.get(key), o)); }, new Map()).values() ); const dedupedArray = dedupeMerge( x => x.name, (o1, o2) => ({ ...o1, url: [o1.url, o2.url].flat() }), originalArray ); console.log(dedupedArray);