我有一个对象数组,其中大多数属性可能彼此重复,但有一个值可能不同:
const originalArray = [
{ id: 1, name: 'x', 'description': 'x', url: 'y' },
{ id: 2, name: 'x', 'description': 'x', url: 'z' }
]
我想根据名称的差异对这个数组进行重复数据删除,但保留URL的差异作为被重复数据删除数组中的数组:
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);
您可以使用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)
将数组缩减为Map,并使用mergeFn
合并重复项。使用Array.from()
或数组扩展将Map.values()
迭代器转换回数组:
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);