JavaScript中的对象集合

70

我想在Javascript中拥有一组对象。也就是说,需要一个仅包含唯一对象的数据结构。

通常建议使用属性来实现,例如 myset["key"] = true。但是,我需要键是对象。我已经阅读过Javascript将属性名称转换为字符串,所以我猜测无法使用 myset[myobject] = true

我可以使用数组,但我需要比O(n)更好的性能来添加、查找和删除项目。

它需要只通过引用来区分对象,因此假设有以下内容:

var a = {};
var b = {};

如果它们是独立的对象,那么ab都应该可以相加。

基本上,我想要像C++的std::set一样的东西,可以存储Javascript对象。有什么想法吗?


可能是JavaScript实现集合数据结构的重复问题 - Ciro Santilli OurBigBook.com
13个回答

0

当在函数前加上this时,似乎内部调用的函数会起作用。例如:

var put;
this.put = put = function(x) {
    if (!this.contains(x))
        list.push(x);

    return this;
}

0

好的,像std::set这样的原生ecmascript类没有比较器功能。当然你可以像其他编程语言一样实现这种数据结构。但是在大多数情况下,我建议使用更简单的方式:

  • 如果您的对象有某种键或id字段,并且您想要O(1)操作(例如查找/添加/更新/删除),则应使用使用此id字段的映射。
  • 如果您没有键,只是想避免集合中的重复项,您可以使用map或甚至set,使用JSON.stringify(o, Object.keys(o).sort())作为ID。如果您具有嵌套的对象或数组,则应该对其项目进行排序(我没有写到这部分)。

我编写了一个可以同时匹配两者的类:

class ObjectSet {
    constructor(iterable) {
        this.map = new Map()
        if(!iterable) {
            return;
        }
        for(o of iterable) {
            this.map.set(this._getId(o), o);
        }
    }

    _getId(o) {
        return o.id ? o.id :
            JSON.stringify(o, Object.keys(o).sort());
    }

    get(id) {
        return this.map.get(id);
    }

    has(o) {
        return this.map.has(this._getId(o));
    }

    //add or update. Call "add" if you want to match ES6 Set interface
    set(o) {
        this.map.set(this._getId(o), o);
    }

    delete(o) {
        this.map.delete(this._getId(o));
    }

    values() {
        return this.map.values();
    }

    [Symbol.iterator] () {
        return this.values();
    }

    get size() {
        return this.map.size;
    }
}

//first use case example, fast find and update:
let objSet = new ObjectSet();

//add
objSet.set({
    id: 1,
    name: "John",
    age: 30
});
const eric = {
    id: 2,
    name: "Eric",
    age: 27
}
//add
objSet.set(eric)
console.log(objSet.size); //2

//update object of id 2
objSet.set({
    id: 2,
    name: "Eric",
    age: 28
})
console.log(objSet.size); // still 2


for(o of objSet) {
    console.log(o);
}
/*
prints:

{ id: 1, name: 'John Abbot', age: 30 }
{ id: 2, name: 'Eric', age: 28 }
*/

objSet.delete({id: 1});//deletes john
objSet.delete(eric);
console.log(objSet.size);//0


//second use case, lets remove duplicated objects using this class
let points = [
    {
        x: 10,
        y: 40
    },
    {
        x: 10,
        y: 40
    },
    {
        x: 10,
        y: 35
    }
]


//lets remove duplicated objects using ObjectSet:
objSet = new ObjectSet(points);
console.log(o.size);//2
for(o of objSet) {
    console.log(o);
}

//same with set method
objSet.set({
    x: 10,
    y: 35
});
console.log(objSet.size);//still 2

-1

请将此代码用作参考。

const fruits = [
  {name: 'apple', price: 100},
  {name: 'apple', price: 100},
  {name: 'orange', price: 200},
  {name: 'grapes', price: 300}
];

const hasFruitDuplicated = () => {
  const duplicatedDeleteFruits = fruits.filter((fruit, index) =>
    fruits.findIndex(item => item.name === fruit.name && item.price === fruit.price) === index
  );
  return duplicatedDeleteFruits;
};


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接