好的,所以我试图创建一个函数,该函数允许您输入对象数组,并且它将返回一个数组,该数组删除了引用内存中相同对象的所有重复对象。可以有具有相同属性的对象,但是它们必须是不同的内存中对象。我知道对象是通过引用存储在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]);
}
任何建议都值得赞赏,我正在尝试使用非常高效的Big-O来做到这一点。干杯!
编辑:如此众多的出色回答。现在,当我使用任意对象属性(类似于答案)运行脚本时,我得到一个空数组。我仍然想尽一切办法过滤掉所有内容,但是继续过滤内存中引用的对象。我不太肯定JS如何处理具有相同确切键/值的对象。再次感谢!
答案 0 :(得分:2)
简单的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
答案 1 :(得分:1)
使用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。
答案 2 :(得分:1)
我看不出执行此map-filter-map组合的充分理由。您只能立即使用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));