I have an array of objects in which most of the properties may be duplicates of each other, but one value may differ:
const originalArray = [
{ id: 1, name: 'x', 'description': 'x', url: 'y' },
{ id: 2, name: 'x', 'description': 'x', url: 'z' }
]
I want to dedupe this array based on a difference of name, but retain the URL differences as an array in the deduped array:
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);
You can use 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)
Reduce the array to a Map, and merge duplicates using a mergeFn
. Convert the Map.values()
iterator back to an array using Array.from()
or 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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.