在javascript中的对象集

Ash*_*ain 39 javascript object set data-structures

我想在Javascript中有一组对象.也就是说,只包含唯一对象的数据结构.

通常建议使用属性,例如myset["key"] = true.但是,我需要将键作为对象.我已经读过Javascript将属性名称转换为字符串,所以我想我不能使用myset[myobject] = true.

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

它需要能够通过引用分开对象,因此给出:

var a = {};
var b = {};
Run Code Online (Sandbox Code Playgroud)

那么这两个ab应该能够被添加,因为它们是独立的对象.

基本上,我正在使用类似C++的东西std::set,它可以存储Javascript对象.有任何想法吗?

Ry-*_*Ry- 21

ES6提供原生Set:

let s = new Set();
let a = {};
let b = {};

s.add(a);

console.log(s.has(a));  // true
console.log(s.has(b));  // false
Run Code Online (Sandbox Code Playgroud)

  • @ndtreviv:不,他们不是同一个对象.`{one:"one"}!== {one:"one"}` (5认同)
  • `new Set([{{one:“ one”},{one:“ one”}]))。size`是2。难道不是1吗? (4认同)
  • 你是对的。我最终使用lodash的_.uniqWith和_.isEqual获得了唯一的对象。 (3认同)

Jim*_*ler 8

这是一个疯狂的建议......关键的结果 JSON.stringify(object)

  • 这是我一直在想的,但我真的不想这样做:/ (4认同)
  • 当对象中的属性顺序不同时,将给出假阴性结果。 (3认同)
  • 类型错误:循环对象值 (2认同)

小智 8

我使用地图,解决了我的问题

const objectsMap = new Map();
const placesName = [
  { place: "here", name: "stuff" },
  { place: "there", name: "morestuff" },
  { place: "there", name: "morestuff" },
];
placesName.forEach((object) => {
  objectsMap.set(object.place, object);
});
console.log(objectsMap);
Run Code Online (Sandbox Code Playgroud)


Mar*_*ahn 7

对于所有对象都不可能,但如果您的对象.toString()实现了一个方法,那么它是:

var x = {toString: function(){ return 'foo'; }};
var y = {toString: function(){ return 'bar'; }};
var obj = {};
obj[x] = 'X';
obj[y] = 'Y';
console.log(obj);
// { foo: 'X', bar: 'Y' }
Run Code Online (Sandbox Code Playgroud)

如果你想让这更容易,那就把它变成一个类:

function myObj(name){
   this.name = name;
}
myObj.prototype.toString = function(){ return this.name; }

var obj = {};
obj[new myObj('foo')] = 'X';
obj[new myObj('bar')] = 'Y';
Run Code Online (Sandbox Code Playgroud)

  • 对于我所关心的一切,`var guid = 0; myObj.prototype.toString = function(){return(this.guid ||(this.guid = guid ++)); 会工作的. (2认同)

Ash*_*ain 6

我正在回答我自己的问题,但我想出了一个我认为很有趣的替代解决方案,并认为分享它会很有用.

cwolves的回答给了我一个主意.提供对象的toString()方法唯一地标识实例,对象的属性可用于存储一组对象.基本上,要存储对象x,您可以使用items[x.toString()] = x;.请注意,该值是对象本身,因此可以通过查看所有item属性并将所有值转储到数组中来提取对象集.

这是我称之为全班的课程ObjectSet.它需要通过toString()方法唯一标识对象,这对我来说是可以的. add,removecontains应优于O(n)的时间都运行-无论JavaScript的属性访问效率,这有望为O(1)或为O(n log n)的.

// Set of objects.  Requires a .toString() overload to distinguish objects.
var ObjectSet = function ()
{
    this.items = {};
    this.item_count = 0;
};

ObjectSet.prototype.contains = function (x)
{
    return this.items.hasOwnProperty(x.toString());
};

ObjectSet.prototype.add = function (x)
{
    if (!this.contains(x))
    {
        this.items[x.toString()] = x;
        this.item_count++;
    }

    return this;
};

ObjectSet.prototype.remove = function (x)
{
    if (this.contains(x))
    {
        delete this.items[x.toString()];
        this.item_count--;
    }

    return this;
};

ObjectSet.prototype.clear = function ()
{
    this.items = {};
    this.item_count = 0;

    return this;
};

ObjectSet.prototype.isEmpty = function ()
{
    return this.item_count === 0;
};

ObjectSet.prototype.count = function ()
{
    return this.item_count;
};

ObjectSet.prototype.values = function ()
{
    var i, ret = [];

    for (i in this.items)
    {
        if (this.items.hasOwnProperty(i))
            ret.push(this.items[i]);
    }

    return ret;
};
Run Code Online (Sandbox Code Playgroud)