在 JavaScript 中创建 Set 的方法?
在 Eloquent JavaScript 第 4 章中,通过创建对象并将值存储为属性名称、分配任意值(例如 true)作为属性值来创建一组值。要检查该值是否已包含在集合中,请使用 in
运算符:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
这是惯用的 JavaScript 吗?使用数组不是更好吗?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
In Eloquent JavaScript, Chapter 4, a set of values is created by creating an object and storing the values as property names, assigning arbitrary values (e.g. true) as property values. To check if the value is already contained in the set, the in
operator is used:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
Is this idiomatic JavaScript? Wouldn't be using an array even better?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
Sets 现已在 ES2015(又名 ES6)中提供,即 ECMAScript 6)。自 2015 年 6 月以来,ES6 一直是 JavaScript 的当前标准。
Axel Rauschmayer 的 书中的前两个示例 探索 ES6:
如果您想了解有关 JavaScript 中 Set 的更多信息,我会查看 探索 ES6 。这本书可以免费在线阅读,但如果您想支持作者Dr. Axel Rauschmayer 您可以花大约 30 美元购买这本书。
如果你现在想使用 Sets 和 ES6,你可以使用 Babel,ES6 到 ES5 的转译器及其 polyfill。
编辑:截至 2017 年 6 月 6 日,大多数主要浏览器在其最新版本中都具有完整的 Set 支持(IE 11 除外)。这意味着如果您不关心支持旧版浏览器,您可能不需要 babel。如果您想查看不同浏览器(包括您当前的浏览器)的兼容性,请检查 Kangax 的 ES6 兼容性表 。
编辑:
只是对初始化进行澄清。集合可以在其构造函数中采用任何同步迭代。这意味着它们不仅可以接受数组,还可以接受字符串和迭代器。以集合的以下数组和字符串初始化为例:
数组和字符串的输出是相同的。请注意
...set1
是 扩展语法。看起来可迭代的每个元素都被一一添加到集合中,因此由于数组和字符串都具有相同的元素,并且由于元素的顺序相同,所以创建的集合是相同的。关于集合需要注意的另一件事是,当迭代它们时,迭代顺序遵循元素插入集合中的顺序。这是迭代集合的示例:由于您可以使用任何迭代器来初始化集合,因此您甚至可以使用 生成器函数。以下是产生相同输出的两个迭代器初始化示例:
这些示例的生成器函数可以编写为不重复,但如果生成器函数更复杂,并且只要以下内容不会对性能产生太大负面影响,您就可以使用 Set 方法来帮助仅从生成器中获取不重复的值不再重复。
如果您想了解有关集合的更多信息而不阅读 Rauschmayer 博士书中的章节,您可以查看 Set 上的 MDN 文档。 MDN 还提供了更多迭代集合的示例,例如使用
forEach
以及使用.keys
、.values
和.entries方法。 MDN 还提供了集合并集、集合交集、集合差值、对称集差值和集合超集检查等示例。希望大多数这些操作都可以在 JavaScript 中使用,而无需构建自己的函数来支持它们。事实上,这个针对新 Set 方法的 TC39 提案 希望添加以下方法如果提案达到第 4 阶段,则在未来某个时间点在 JavaScript 中设置:
Sets are now available in ES2015 (aka ES6, i.e. ECMAScript 6). ES6 has been the current standard for JavaScript since June 2015.
First two examples from Axel Rauschmayer's book Exploring ES6:
I would check out Exploring ES6 if you want to learn more about Sets in JavaScript. The book is free to read online, but if you would like to support the author Dr. Axel Rauschmayer you can purchase the book for around $30.
If you want to use Sets and ES6 now you can use Babel, the ES6 to ES5 transpiler, and its polyfills.
Edit: As of June 6th, 2017 most of the major browsers have full Set support in their latest versions (except IE 11). This means you may not need babel if you don't care to support older browsers. If you want to see compatibility in different browsers including your current browser check Kangax's ES6 compatibility table.
EDIT:
Just clarification on initialization. Sets can take any synchronous iterable in their constructor. This means they can take not just arrays but also strings, and iterators. Take for example the following array and string initialization of a set:
Both outputs of the array and string are the same. Note that
...set1
is the spread syntax. It appears that each element of the iterable is added one by one to the set, so since both the array and string have the same elements and since the elements are in the same order the set is created the same. Another thing to note about sets is when iterating over them the iteration order follows the order that the elements were inserted into the set. Here's an example of iterating over a set:Since you can use any iterable to initialize a set you could even use a iterator from a generator function. Here is two such examples of iterator initializations that produce the same output:
These examples' generator functions could just be written to not repeat, but if the generator function is more complicated and as long as the following doesn't impact performance too negatively you could use the Set method to help get only values from a generator that don't repeat.
If you want to know more about sets without reading Dr. Rauschmayer's chapter of his book you can check out the MDN docs on Set. MDN also has more examples of iterating over a set such as using
forEach
and using the.keys
,.values
, and.entries
methods. MDN also has examples such as set union, set intersection, set difference, symmetric set difference, and set superset checking. Hopefully most of those operations will become available in JavaScript without needing to build your own functions supporting them. In fact, there is this TC39 proposal for new Set methods which should hopefully add the following methods to Set in JavaScript at some future point in time if the proposal reaches stage 4:我使用 dict 对象作为集合。这适用于字符串和数字,但我想如果您想要使用自定义相等和比较运算符拥有一组对象,则会出现问题:
创建集合:
测试是否包含在集合中< /strong>
向集合中添加元素
从集合中删除元素
delete example_set['a']
;I use dict objects as sets. This works with strings and numbers, but I suppose would cause problems if you wanted to have a set of objects using custom equality and comparison operators:
Creating a set:
Testing for inclusion in a set
Adding an element to a set
Removing an element from a set
delete example_set['a']
;集合不允许重复条目,并且通常不保证预定义的排序。数组同时执行这两项操作,因此违反了集合的含义(除非您进行额外的检查)。
Sets do not allow duplicate entries and don't typically guarantee predefined ordering. Arrays do both of these, thus violating what it means to be a set (unless you do additional checks).
第一种方法是惯用的 JavaScript。
每当您想要存储键/值对时,都必须使用 JavaScript 对象。对于数组来说,有几个问题:
索引是一个数值。
没有简单的方法可以在不循环的情况下检查值是否在数组中。
集合不允许重复。数组可以。
The first way is idiomatic JavaScript.
Any time you want to store a key/value pair, you must use a JavaScript object. As for arrays, there are several problems:
The index is a numerical value.
No easy way to check to see if a value is in an array without looping through.
A set doesn't allow duplicates. An array does.
如果你想从数组创建一个集合,只需这样做:
这是我在使用 Python 编程时非常喜欢的糖语法,很高兴 ES6 终于可以做同样的事情了。
注意:然后我意识到我所说的并没有直接回答你的问题。在 ES5 中进行这种“hack”的原因是因为通过键在对象中查找时间 (O(1)) 比在数组 (O(n)) 中查找时间要快得多。在性能关键型应用程序中,您可以牺牲一点可读性或直觉来获得更好的性能。
但是,嘿,欢迎来到 2017 年,现在您可以在所有主要的现代浏览器中使用正确的 Set 了!
If you want to create a set from an array, simply do:
This is a sugar syntax that I quite fancied when programming in Python, so glad that ES6 finally made it possible to do the same thing.
NOTE: then I realize what I said didn't directly answer your question. The reason you have this "hack" in ES5 is because lookup time in an object by keys is significantly faster (O(1)) than in an array (O(n)). In performance critical applications, you can sacrifice this bit of readability or intuition for better performance.
But hey, welcome to 2017, where you can use proper Set in all major modern browsers now!
ES6
/ES2015
中的集合:ES6
/ES2015
现在具有内置集合。集合是一种数据结构,它允许存储任何类型的唯一值,无论是原始值还是对象引用。可以通过以下方式使用ES6
内置 set 构造函数来声明集合:使用 Set 构造函数创建集合时,我们新创建的 set 对象继承自
Set.prototype
。它具有各种辅助方法和属性。这使您可以轻松执行以下操作:示例:
浏览器兼容性:
除了 IE 缺少某些功能外,所有主要浏览器现在都完全支持其他浏览器。如需准确参考,请参阅 mdn 文档 。
Sets in
ES6
/ES2015
:ES6
/ES2015
now has built in sets. A set is data structure which allows storage of unique values of any type, whether this are primitive values or object references. A set can be declared using theES6
built in set constructor in the following manner:When creating a set using the Set constructor our newly created set object inherits from the
Set.prototype
. This has all sorts of auxiliary methods and properties. This allows you to easily do the following things:Example:
Browser compatibility:
All major browser now fully support sets except IE where some features are missing. For exact reference please refer to the mdn docs.
使用裸 JavaScript 对象来模拟集合有两个问题:首先,对象可以具有继承的属性,这会破坏“in”运算符;其次,您只能以这种方式存储标量值,不能创建一组对象可能的。因此,Sets 的实际实现应该提供方法
add
和contains
,而不是简单的in
和属性赋值。There are two problems with using bare javascript objects to emulate sets: first, an object can have an inherited property which would screw the "in" operator and second, you can only store scalar values in this way, making a set of objects is not possible. Therefore, a realistic implementation of Sets should provide methods
add
andcontains
instead of plainin
and property assignments.您可以尝试 Buckets,它是一个 JavaScript 数据结构库,拥有操作集合所需的一切。
You can try Buckets, is a javascript data structure library and has everything you need to manipulate sets.
Set 对象
Basic creation and usage of Set object ????
Iteration
Convert to array