我有一个包含对象数组的对象。
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"}
让myData=[{place:“here”,name:“stuff”},{地点:“there”,名称:“morestuff”},{地点:“there”,名称:“morestuff”}];let q=[…new Map(myData.Map(obj=>[JSON.stringify(obj),obj]).values()];控制台日志(q)
一个使用ES6和new Map()的命令行。
// assign things.thing to myData
let myData = things.thing;
[...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];
详细信息:-
对数据列表执行.map()并将每个单独的对象转换为[key,value]对数组(长度=2),第一个元素(key)将是对象的字符串化版本,第二个元素(value)将是一个对象本身。将上述创建的数组列表添加到新的Map()中会将键作为字符串化对象,任何相同的键添加都会导致覆盖现有的键。使用.values()将为MapIterator提供Map中的所有值(在本例中为obj)最后,传播。。。运算符为新数组提供上述步骤中的值。
向列表中再添加一个。将ES6和Array.reduce与Array.find一起使用。在此示例中,根据guid属性筛选对象。
let filtered = array.reduce((accumulator, current) => {
if (! accumulator.find(({guid}) => guid === current.guid)) {
accumulator.push(current);
}
return accumulator;
}, []);
扩展此选项以允许选择属性并将其压缩为一行:
const uniqify = (array, key) => array.reduce((prev, curr) => prev.find(a => a[key] === curr[key]) ? prev : prev.push(curr) && prev, []);
要使用它,请将对象数组和要进行重复数据消除的键的名称作为字符串值传递:
const result = uniqify(myArrayOfObjects, 'guid')
带过滤器的内衬(保留订单)
在数组中查找唯一id。
arr.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i)
如果顺序不重要,映射解决方案将更快:使用映射解决方案
多个财产独有(地点和名称)
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)
通过用findLastIndex替换findIndex来保留最后一次出现。
arr.filter((v,i,a)=>a.findLastIndex(v2=>(v2.place === v.place))===i)