我有一个包含对象数组的对象。
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"}
向列表中再添加一个。将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')
removeDucplicates()接受一个对象数组,并返回一个没有任何重复对象的新数组(基于id属性)。
const allTests = [
{name: 'Test1', id: '1'},
{name: 'Test3', id: '3'},
{name: 'Test2', id: '2'},
{name: 'Test2', id: '2'},
{name: 'Test3', id: '3'}
];
function removeDuplicates(array) {
let uniq = {};
return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true))
}
removeDuplicates(allTests);
预期结果:
[
{name: 'Test1', id: '1'},
{name: 'Test3', id: '3'},
{name: 'Test2', id: '2'}
];
首先,我们将变量uniq的值设置为空对象。
接下来,我们过滤对象数组。Filter创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。
return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));
上面,我们使用了&&的短路功能。如果&&的左侧求值为true,则返回&&右侧的值。如果左侧为false,则返回&&左侧的内容。
对于每个对象(obj),我们检查uniq中名为obj.id值的属性(在这种情况下,在第一次迭代时,它将检查属性“1”。)我们希望它返回的结果(true或false)相反,这就是为什么我们使用!在里面uniq[obj.id]。如果uniq已经具有id属性,则返回true,其计算结果为false(!),告诉过滤函数不要添加该obj。但是,如果未找到obj.id属性,它返回false,然后计算结果为true(!)并返回&&或(uniq[obj.id]=true)右侧的所有内容。这是一个truthy值,告诉filter方法将该obj添加到返回的数组中,并且还将属性{1:true}添加到uniq中。这确保不会再添加具有相同id的任何其他obj实例。