JavaScript中是否有类似Java集的数据结构?
我想在JavaScript中使用一个数据结构,可以用来存储ID的数量。我应该能够检查该集合中是否已经存在一个键,比如Java集合 我希望实现如下相同的行为(此代码是Java的):JavaScript中是否有类似Java集的数据结构?,java,javascript,dojo,set,Java,Javascript,Dojo,Set,我想在JavaScript中使用一个数据结构,可以用来存储ID的数量。我应该能够检查该集合中是否已经存在一个键,比如Java集合 我希望实现如下相同的行为(此代码是Java的): Set st=new HashSet(); //添加元素 如果(st.contains(“aks”)){ //做点什么 } 我想要一个与上述代码等价的JavaScript/dojo。可能有一个关联数组/哈希表/字典(我不知道它到底是如何调用的),使用set元素作为键,“其他任何东西”作为值 insert: mySet
Set st=new HashSet();
//添加元素
如果(st.contains(“aks”)){
//做点什么
}
我想要一个与上述代码等价的JavaScript/dojo。可能有一个关联数组/哈希表/字典(我不知道它到底是如何调用的),使用set元素作为键,“其他任何东西”作为值
insert: mySet[key] = "Whatever";
delete: mySet[key] = null;
check: if (mySet[key] != null) { ... }
为什么不使用普通对象并检查JavaScript的
hasOwnProperty
是否存在键
var x = {};
x['key'] = 'val';
x.hasOwnProperty('key'); // true //
x.hasOwnProperty('key2'); // false //
下面是一个更高级的用例:
var x = {};
var prefix = 'item_';
for(var i=0;i<10;i++){
x[prefix+i] = 'value '+(i+1);
}
x.hasOwnProperty('item_6'); // true //
x.hasOwnProperty('other key'); // false //
Hash是实现Set的很好的候选者。您可以使用如下函数创建一个集合:
function set () {
var result = {};
for (var i = 0; i < arguments.length; i++) result[arguments[i]] = true;
return result;
}
集合没有键。它们只有一组值,但映射有成对的键/值实体 因此,您有两种选择。每种方法都有其缺点和优点:
附言:还有一件事。数组实际上也是对象。因此,它们也可以用作哈希表/映射 我已经编写了一个JavaScript哈希集实现,它可以满足您的需要,并允许任何对象成为该集的成员: 但是,如果只需要存储字符串,则可以通过将集合成员存储为普通对象的属性名来完成更简单的操作。例如:
function StringSet() {
var setObj = {}, val = {};
this.add = function(str) {
setObj[str] = val;
};
this.contains = function(str) {
return setObj[str] === val;
};
this.remove = function(str) {
delete setObj[str];
};
this.values = function() {
var values = [];
for (var i in setObj) {
if (setObj[i] === val) {
values.push(i);
}
}
return values;
};
}
关于实现的注意事项:val
是StringSet
实现内部使用的对象,每个集都是唯一的。将属性名称构成集合(setObj
)的对象的属性值与val
进行比较,无需进行hasOwnProperty()
检查,并确保只有添加到集合中的字符串才会显示在值中
用法示例:
var set = new StringSet();
set.add("foo");
set.add("bar");
alert(set.contains("foo")); // true
alert(set.contains("baz")); // false
set.values(); // ["foo", "bar"], though not necessarily in that order
set.remove("foo");
set.values(); // ["bar"]
不需要Dojo,这是Javascript固有的。使用对象。听起来您只需要键,而不需要值。查找是固定时间
var st = {'aks':1, 'foo':1, 'bar':1}; // or could start with empty {}. 1 could be any value of any type, it's just short.
//add elements
st.baz = 1;
//or load up dynamically
myArrayOfStrings.forEach(function(key){
st[key] = 1;
});
if("aks" in st){
//do something
}
感谢您的回复。但我如何检查它是否包含键?我想在javascriptSee last edit中获得它。请参阅上次编辑,试图澄清。@G B它被称为对象。这是JavaScript的基本数据类型。@G B实际上,在检查的情况下,正确的方法是比较未定义的:如果(mySet[key]!==未定义的){…}
。在JavaScript中,一个项目仍然可以存在,并且其值为null
。更正:正确检查的唯一方法是使用hasOwnProperty
。感谢您的回复:我想先向对象动态添加多个键,然后再检查对象中是否存在键。怎么做?@键可以是任何字符串(甚至是包含字符串的变量)。我将用一个例子进行更新。@gbwithdelete x['key']代码>。同样,钥匙可以是任何东西。我使用文字只是为了方便。不一定是:Object.prototype.foo=“true”;警报(x[“foo”]==true)
如果您正在创建一个简单的对象,并且原型不是问题,只需使用“in”操作符即可。它读起来好多了。像x[“foo”]这样的静态查找可以写为x.foo。forEach
在IE中不受支持。这还需要一个hasOwnProperty()
检查,以防其他代码执行了类似Object.prototype.aks=1
的操作。是的,在我的示例中,我假设ES5没有人修改对象原型,这是最佳实践。避免调用hasOwnProperty()的目的是什么?平等性检查是否更快?如果是这样,你怎么知道?@JørgenFogh:我怀疑等式检查可能更快,因为它避免了函数调用的开销。我还没有测试过这个,所以请随意创建一个基准;我很想看看结果。@JørgenFogh:对象比较的另一个优点是它不会出错。
function StringSet() {
var setObj = {}, val = {};
this.add = function(str) {
setObj[str] = val;
};
this.contains = function(str) {
return setObj[str] === val;
};
this.remove = function(str) {
delete setObj[str];
};
this.values = function() {
var values = [];
for (var i in setObj) {
if (setObj[i] === val) {
values.push(i);
}
}
return values;
};
}
var set = new StringSet();
set.add("foo");
set.add("bar");
alert(set.contains("foo")); // true
alert(set.contains("baz")); // false
set.values(); // ["foo", "bar"], though not necessarily in that order
set.remove("foo");
set.values(); // ["bar"]
var st = {'aks':1, 'foo':1, 'bar':1}; // or could start with empty {}. 1 could be any value of any type, it's just short.
//add elements
st.baz = 1;
//or load up dynamically
myArrayOfStrings.forEach(function(key){
st[key] = 1;
});
if("aks" in st){
//do something
}