如何在JavaScript中创build一个集合?

在第四章的Eloquent JavaScript中,通过创build一个对象并将值存储为属性名称,将任意值(例如true)赋值为属性值来创build一组值。 要检查该值是否已经包含在集合中,则使用in运算符:

 var set = {}; if (!'Tom' in set) { set.Tom = true; } 

这是惯用的JavaScript吗? 不会使用更好的数组?

 var set = []; if (!'Tom' in set) { set.push = 'Tom'; } 

套件现在在ES2015(又名ES6,即ECMAScript 6)中可用。 自2015年6月以来,ES6一直是JavaScript的最新标准。

ECMAScript 6具有适用于任意值的数据结构Set,速度较快,能够正确处理NaN。 – Axel Rauschmayer , 探索ES6

前两个例子来自Axel Rauschmayer的书“ 探索ES6 :

pipe理单个元素:

 > let set = new Set(); > set.add('red') > set.has('red') true > set.delete('red') true > set.has('red') false 

确定Set的大小并清除它:

 > let set = new Set(); > set.add('red') > set.add('green') > set.size 2 > set.clear(); > set.size 0 

如果你想了解更多关于在JavaScript中设置,我会检查出探索ES6 。 这本书可以免费在线阅读,但如果您想支持作者Axel Rauschmayer博士,您可以购买该书约30美元。

如果你现在想要使用Sets和ES6,你可以使用Babel ,ES6到ES5的编译器,以及它的polyfills。

编辑:截至2017年6月6日,大多数主stream浏览器都有最新版本的全套支持。 这意味着如果您不在意支持旧版浏览器,您可能不需要使用babel。 如果您想在不同的浏览器(包括您当前的浏览器)中查看兼容性,请检查Kangax的ES6兼容性表 。

我使用dict对象作为集合。 这与string和数字的作品,但我想如果你想要使用自定义相等和比较运算符的一组对象会导致问题:

创build一个集合:

 var example_set = { 'a':true, 'b':true, 'c':true } 

testing包含在一个集合中

 if( example_set['a'] ){ alert('"a" is in set'); } 

将一个元素添加到一个集合

 example_set['d'] = true; 

从一个集合中删除一个元素

delete example_set['a'] ;

集不允许重复的条目,通常不保证预定义的顺序。 数组可以完成这两个操作,从而违反了成为一个集合的含义(除非您进行额外的检查)。

第一种方法是惯用的JavaScript。

任何时候你想存储一个键/值对,你必须使用一个JavaScript对象。 至于arrays,有几个问题:

  1. 该指数是一个数值。

  2. 没有简单的方法来检查一个值是否在没有循环的数组中。

  3. 一套不允许重复。 一个数组呢。

使用裸JavaScript对象来模拟集有两个问题:首先,一个对象可以有一个inheritance的属性,这将导致“in”操作符,其次,只能以这种方式存储标量值,使一组对象不是可能。 因此,集合的一个现实的实现应该提供方法addcontains而不是简单的in和属性分配。

您可以尝试Buckets ,它是一个JavaScript数据结构库,并具有处理集合所需的所有内容。

如果你想从数组中创build一个集合,只需要:

 let arr = [1, 1, 2, 1, 3]; let mySet = new Set(arr); // Set { 1, 2, 3 } 

这是在Python编程时我很喜欢的一种糖语法,很高兴ES6最终能够做同样的事情。

注:然后我意识到我所说的没有直接回答你的问题。 你在ES5中有这个“破解”的原因是因为键在对象中的查询时间要比在数组(O(n))中快得多(O(1))。 在性能关键的应用程序中,您可以牺牲这种直觉的可读性,并具有更好的性能。

但是,嘿,欢迎到2017年,在那里你可以使用适当的所有主stream的现代浏览器!