好了,所以我想创建一个功能,可以让你输入对象的数组,它会返回删除指向同一对象在内存中的任何重复对象的数组。可以有具有相同属性的对象,但它们必须是不同的内存中的对象。我知道,对象是通过引用存储在JS,这是我到目前为止有:
const unique = array => {
let set = new Set();
return array.map((v, index) => {
if(set.has(v.id)) {
return false
} else {
set.add(v.id);
return index;
}
}).filter(e=>e).map(e=>array[e]);
}
任何建议表示赞赏,我想有一个非常高效的大O,使这个。干杯!
编辑:这么多真棒响应。现在,当我运行任意对象属性的脚本(类似的答案),我得到一个空数组。我仍然试图环绕过滤所有的东西,但对在内存中引用的对象我的头。我不积极JS如何处理与完全相同的键/值的对象。再次感谢!
简单Set会做的伎俩
let a = {'a':1}
let b = {'a': 1,'b': 2, }
let c = {'a':1}
let arr = [a,b,c,a,a,b,b,c];
function filterSameMemoryObject(input){
return new Set([...input])
}
console.log(...filterSameMemoryObject(arr))
我不认为你需要这么多的代码,你只是比较存储器的引用可以使用===
- > equality and sameness。
let a = {'a':1}
console.log(a === a ) // return true for same reference
console.log( {} === {}) // return false for not same reference
我没有看到一个很好的理由这样做地图 - 过滤 - 地图组合。你可以只用filter
马上:
const unique = array => {
const set = new Set();
return array.filter(v => {
if (set.has(v.id)) {
return false
} else {
set.add(v.id);
return true;
}
});
};
此外,如果您array
包含要参照来比较,不是由他们.id
的对象,你甚至都不需要过滤自己。你可以这样写:
const unique = array => Array.from(new Set(array));
使用Set
的想法是好的,但一个Map
将工作更好的,那么你可以做到这一切在构造函数中的回调:
const unique = array => [...new Map(array.map(v => [v.id, v])).values()]
// Demo:
var data = [
{ id: 1, name: "obj1" },
{ id: 3, name: "obj3" },
{ id: 1, name: "obj1" }, // dupe
{ id: 2, name: "obj2" },
{ id: 3, name: "obj3" }, // another dupe
];
console.log(unique(data));
你引用同一个对象在内存中的项目发言。当您的数组初始化为纯文本这样的事情不会发生,但如果分配在同一个对象的几个数组项,那么你得到的重复引用,就像这样:
const obj = { id: 1, name: "" };
const data = [obj, obj];
这是不一样的东西:
const data = [{ id: 1, name: "" }, { id: 1, name: "" }];
在第二个版本,你有你的阵列中的两个不同的引用。
我假设你想“捕获”这样的重复也。如果只考虑重复什么是在第一个版本(共享引用)提出,然后this was asked before。