在JavaScript中创建Set的方法?

时间:2011-12-02 22:35:40

标签: 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';
}

9 个答案:

答案 0 :(得分:82)

Sets现在可用于ES2015(又名ES6,即ECMAScript 6)。自2015年6月以来,ES6一直是JavaScript的当前标准。

  

ECMAScript 6具有适用于任意的数据结构Set   值,快速并正确处理NaN。 - Axel RauschmayerExploring ES6

Axel Rauschmayer's本书Exploring ES6中的前两个例子:

  

管理单个元素:

> 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中的集合的更多信息,我会查看Exploring ES6。这本书可以免费在线阅读,但如果你想支持作者Dr. Axel Rauschmayer,你可以以30美元左右的价格购买这本书。

如果你现在想使用套装和ES6,你可以使用Babel,ES6到ES5的转换器及其polyfill。

编辑:截至2017年6月6日,大多数主流浏览器在其最新版本(IE 11除外)中都有完整的Set支持。这意味着如果您不关心支持旧版浏览器,则可能不需要使用babel。如果您想查看包括当前浏览器在内的不同浏览器的兼容性,请选中Kangax's ES6 compatibility table

答案 1 :(得分:31)

我使用dict对象作为集合。这适用于字符串和数字,但是如果你想使用自定义相等和比较运算符来创建一组对象,我想会产生问题:

创建一个集合

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

测试是否包含在

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

将元素添加到集合

example_set['d'] = true;

从集合中移除元素

delete example_set['a'];

答案 2 :(得分:15)

集合不允许重复条目,通常不保证预定义的排序。数组执行这两个操作,因此违反了集合的含义(除非您进行其他检查)。

答案 3 :(得分:11)

第一种方式是惯用的JavaScript。

只要您想存储键/值对,就必须使用JavaScript对象。至于数组,有几个问题:

  1. 索引是一个数值。

  2. 没有简单的方法可以检查数据是否在数组中而没有循环。

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

答案 4 :(得分:7)

如果要从数组创建集合,只需执行:

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

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

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

但是,嘿,欢迎来到2017年,您现在可以在所有主流现代浏览器中使用正确的设置

答案 5 :(得分:4)

ES6 / ES2015中设置:

ES6 / ES2015现在具有内置集合。集合是一种数据结构,它允许存储任何类型的唯一值,无论是原始值还是对象引用。可以使用内置ES6的内置构造函数以以下方式声明一个集合:

const set = new Set([1, 2, 3, 4, 5]);

使用Set构造函数创建集合时,我们新创建的集合对象继承自Set.prototype。这具有各种辅助方法和属性。这使您可以轻松地执行以下操作:

示例:

const set = new Set([1, 2, 3, 4, 5]);

// checkout the size of the set
console.log('size is: ' + set.size);

// has method returns a boolean, true if the item is in the set
console.log(set.has(1));

// add a number
set.add(6);

// delete a number
set.delete(1);

// iterate over each element using a callback
set.forEach((el) => {
  console.log(el);
});

// remove all the entries from the set
set.clear();

浏览器兼容性:

除了缺少某些功能的IE之外,所有主流浏览器现在都完全支持集。有关确切的参考,请参阅mdn docs

答案 6 :(得分:3)

使用裸javascript对象来模拟集合有两个问题:首先,一个对象可以有一个继承的属性,它会拧紧“in”运算符,其次,你只能以这种方式存储标量值,制作一组对象是不可能的。因此,集合的实际实现应提供方法addcontains,而不是普通in和属性分配。

答案 7 :(得分:3)

你可以尝试Buckets,它是一个javascript数据结构库,拥有操作集所需的一切。

答案 8 :(得分:1)

Set对象?的基本创建和使用

let mySet = new Set()

mySet.add(2)         // Set {2}
mySet.add(7)         // Set {2, 7}
mySet.add(7)         // Set {2, 7}
mySet.add('my text') // Set {2, 7, 'my text'}
let myObj = { a: 1, b: 2 }
mySet.add(myObj)     // Set {2, 7, 'my text', {...}}
mySet.has(2)         // true
mySet.has(myObj)     // true
mySet.size           // 4

迭代

for (let item of mySet) console.log(item)  // 2, 7, 'my text', {a:1, b:2}
mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}

转换为数组

var myArr = Array.from(mySet)             // [2, 7, 'my text', {a:1, b:2}]

❕Set提供的最独特功能是Set对象中的每个值都必须是 独特。因此,您不能添加重复的值。