我有一个这样的数组:
[1, {a: 'b', c: 'd'}, {c: 'd', a: 'b'}, {e: 'f'}, 'b']
我想要做的是我想从这个数组中删除重复项,无论它们是否为对象,以便最终的数组可以成为:
[1, {a: 'b', c: 'd'}, {e: 'f'}, 'b']
我在网站上看到过很多解决方案,但没有一个能解决我的问题。我怎么能这样做?
我试过了:
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
但这也删除了第三个对象。
感谢。
答案 0 :(得分:0)
如果您只想比较参考而不是对象的内容,可以使用:
arr.reduce(function(accumulator, element){
if (accumulator.indexOf(element) !== -1) return accumulator;
return accumulator.concat(element);
}, []);
否则,您需要创建一个比较对象内容的函数,例如:
function objectsMatch(obj1, obj2) {
if (obj1 === obj2) return true;
for (var prop in obj1) {
if (!(prop in obj2) || obj1[prop] !== obj2[prop]) return false;
}
for (var prop in obj2) {
if (!(prop in obj1)) return false;
}
return true;
}
然后使用类似的东西:
arr.reduce(function(accumulator, element){
if (accumulator.some(function(otherElement){
return objectsMatch(element, otherElement);
})) return accumulator;
return accumulator.concat(element);
}, []);
答案 1 :(得分:0)
此功能将为您完成。它使用Object.keys()
来交叉引用对象。如果看到的是使用已知密钥填充并且已知密钥内容是看到的对象的密钥内容的两倍,则从对象中删除属性。最后,如果object为空,则使用splice从数组中删除整个对象。请注意,此解决方案仅在所有输入与提供的示例类似时才有效。否则函数需要递归写入。
var abc = [1, {a: 'b', c: 'd'}, {c: 'd', a: 'b'}, {e: 'f'}, 'b'];
function uniq_fast(a) {
var seen = {};
var deleteObject = [];
var len = a.length;
for(var i = 0; i < len; i++) {
if (Object.prototype.toString.call(a[i]) === '[object Array]' || Object.prototype.toString.call(a[i]) === '[object Object]')
{
var test = Object.keys(a[i]);
var len2 = test.length;
for (var j = 0; j < len2; ++j)
{
if (seen[test[j]] && a[i][test[j]] === seen[test[j]])
{
delete a[i][test[j]];
}
else
{
seen[test[j]] = a[i][test[j]];
}
}
if (Object.keys(a[i]).length == 0)
{
deleteObject.push(i);
}
}
}
for (var i = 0; i < deleteObject.length; ++i)
{
a.splice(deleteObject[i], 1);
}
return a;
}
console.log(uniq_fast(abc));