创建一个JavaScript函数以过滤掉重复的内存对象?

时间:2019-02-05 16:44:32

标签: javascript

好的,所以我试图创建一个函数,该函数允许您输入对象数组,并且它将返回一个数组,该数组删除了引用内存中相同对象的所有重复对象。可以有具有相同属性的对象,但是它们必须是不同的内存中对象。我知道对象是通过引用存储在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如何处理具有相同确切键/值的对象。再次感谢!

3 个答案:

答案 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));