javascript中的对象集

| 我想用Javascript拥有一组对象。即,仅包含唯一对象的数据结构。 通常建议使用属性,例如
myset[\"key\"] = true
。但是,我需要键成为对象。我已经读过Javascript将属性名称转换为字符串,所以我想我不能使用
myset[myobject] = true
。 我可以使用数组,但是我需要比O(n)性能更好的东西来添加,查找和删除项目。 它需要能够仅通过引用将对象区分开,因此给出:
var a = {};
var b = {};
那么应该可以同时添加
a
b
,因为它们是独立的对象。 基本上,我追求的是C ++的
std::set
之类的东西,可以存储Javascript对象。有任何想法吗?     
已邀请:
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
这是一个疯狂的建议...将ѭ8的结果作为关键     
不可能对所有对象都有效,但是如果您的对象实现了
.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\' }
如果您想简化此过程,请使其成为一类:
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\';
    
我正在回答自己的问题,但是我想出了一个替代解决方案,我认为这很有趣,并且认为共享它很有用。 狼的回答给了我一个主意。如果提供对象的“ 12”方法唯一标识实例,则可以使用对象的属性存储一组对象。本质上,要存储对象
x
,可以使用
items[x.toString()] = x;
。请注意,值是对象本身,因此可以通过查看ѭ15的所有属性并将所有值转储到数组中来提取对象集。 这是全班,我叫16英镑。它要求对象通过它们的“ 12”方法进行唯一标识,这对我来说是可以的。
add
remove
contains
应该都比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;
};
    
对于您要执行的操作(对象集),没有本机Javascript实现。您将必须自己实现。一种实现方法是为对象实现哈希函数。该集合的支持数据类型将是一个关联数组,其中数组的键是您从调用对象的哈希函数获得的值,而数组的值是对象本身。 当然,这不能解决您强调的问题,因此您还需要考虑平等性(也许要实现一个平等性功能)? 您可以拥有一个独立的哈希函数,该哈希函数将对象作为输入并生成哈希值(大概是通过迭代其属性),而不是使哈希函数成为对象本身的属性。 使用此方法,您应该能够获得
O(1)
以便进行插入,搜索和删除(不计算哈希函数的顺序,这不应该比
O(n)
差,特别是如果您要遍历其属性以创建哈希表时)值)。     
ECMAScript6
Set
应该表现为: 标准:http://www.ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw 非官方的ES6备忘单:https://github.com/lukehoban/es6features#map--set--weakmap--weakset 在Firefox 32上的工作示例(但未在Chromium 37中实现):
if (Set) {
  var s = new Set()
  var a = {}
  var b = {}
  var c = {}
  s.add(a)
  s.add(b)
  s.add(b)
  assert(s.size === 2)
  assert(s.has(a))
  assert(s.has(b))
  assert(!s.has(c))
}
{} != {}
开始,这并不奇怪:缺省情况下,相等比较对象地址。 在不支持的浏览器中实现该模块的模块:https://github.com/medikoo/es6-set     
只需输入此内容,即可对其进行简要测试:
var Set = function Set()
{
    var list = [];

    var contains;
    this.contains = contains = function(x) {
        return list.indexOf(x) >= 0;
    }

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

        return this;
    }

    var remove;
    this.remove = remove = function(x)
    {
        var idx = list.indexOf(x);
        if (idx >= 0)
            list.splice(idx,1);

        return this;
    }

    var all;
    this.all = all = function()
    {
        return list.concat();
    }

    return this;
}
    
似乎在函数内部调用带有此前缀时有效。 范例:
var put;
this.put = put = function(x) {
    if (!this.contains(x))
        list.push(x);

    return this;
}
    

要回复问题请先登录注册