如何从对象数组中删除所有重复项?
如何从对象数组中删除所有重复项?
我有一个包含对象数组的对象。
obj = {}; obj.arr = new Array(); obj.arr.push({place:"here",name:"stuff"}); obj.arr.push({place:"there",name:"morestuff"}); obj.arr.push({place:"there",name:"morestuff"});
我想知道从数组中删除重复对象的最佳方法是什么。例如,obj.arr
将变为...
{place:"here",name:"stuff"}, {place:"there",name:"morestuff"}
admin 更改状态以发布 2023年5月25日
使用过滤器的一行代码(保持顺序)
在数组中查找唯一的id
。
arr.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i)
如果顺序不重要,使用映射解决方案会更快:使用映射的解决方案
按多个属性(place
和name
)去重
arr.filter((v,i,a)=>a.findIndex(v2=>['place','name'].every(k=>v2[k] ===v[k]))===i)
按所有属性去重(对于大型数组而言,这将很慢)
arr.filter((v,i,a)=>a.findIndex(v2=>(JSON.stringify(v2) === JSON.stringify(v)))===i)
保留最后一次出现的,通过用findIndex
替换findLastIndex
。
arr.filter((v,i,a)=>a.findLastIndex(v2=>(v2.place === v.place))===i)
那么,使用ES6的魔力怎么样?
obj.arr = obj.arr.filter((value, index, self) => index === self.findIndex((t) => ( t.place === value.place && t.name === value.name )) )
一个更通用的解决方案是:
const uniqueArray = obj.arr.filter((value, index) => { const _value = JSON.stringify(value); return index === obj.arr.findIndex(obj => { return JSON.stringify(obj) === _value; }); });
使用上面的属性策略,而不是JSON.stringify
:
const isPropValuesEqual = (subject, target, propNames) => propNames.every(propName => subject[propName] === target[propName]); const getUniqueItemsByProperties = (items, propNames) => items.filter((item, index, array) => index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNames)) );
您可以添加一个包装器,如果您希望propNames
属性既是数组也是值:
const getUniqueItemsByProperties = (items, propNames) => { const propNamesArray = Array.from(propNames); return items.filter((item, index, array) => index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNamesArray)) ); };
可以同时允许getUniqueItemsByProperties('a')
和getUniqueItemsByProperties(['a']);
解释