3.关于JavaScript集合-你需要知道的一切

132 阅读5分钟

JavaScript对象​和数组​是最常用的数据结构,充当数据集合。在ES6​之前,开发人员的选择有限。但是有了ES6,我们有了两种新的灵活且易于使用的数据结构,Map​和Set​。

Set

​Set​是唯一​(不同)元素的集合,其中每个元素可以是任何类型。Set​也是元素的有序集合。这意味着元素的检索顺序将与插入顺序相同。

JavaScript 的set集合行为方式与数学集相同。

创建一个Set

const set = new Set();
console.log(set);

输出

Set(0) {}

初始化一个Set集合并创建

const fruteSet = new Set(['🍉', '🍎', '🍈', '🍏']);
console.log(fruteSet);

输出

Set(4) {"🍉", "🍎", "🍈", "🍏"}

设置方法-让我们做一些沙拉🥗!

​Set​具有向其添加元素、从中删除元素、检查其中是否存在元素以及完全清除它的方法。让我们通过做一些沙拉来看看它!

添加蔬菜

使用​add(element)​方法将元素添加到Set。

const saladSet = new Set(); 
saladSet.add('🍅'); 
saladSet.add('🥑'); 
saladSet.add('🥕'); 
saladSet.add('🥒'); 
console.log(saladSet);

好了,我们已经添加了蔬菜。到目前为止的输出

Set(4) {"🍅", "🥑", "🥕", "🥒"}

再加一根黄瓜——我们可以吗?

我喜欢黄瓜!再加一个怎么样?我可以吗?哦,不,我不能。set​是唯一的​元素的集合。

saladSet.add('🥒');
console.log(saladSet);

输出仍然和以前一样,没有任何东西添加到saladSet​中

Set(4) {"🍅", "🥑", "🥕", "🥒"}

它有胡萝卜(🥕)或西兰花(🥦)吗?

使用​has(element)​方法搜索Set​中的元素。

console.log('沙拉里有胡萝卜吗?', saladSet.has('🥕')); 
console.log('沙拉里有西兰花吗??', saladSet.has('🥦'));

使用​delete(element)​方法从Set​中删除元素。

saladSet.delete('🥑');
console.log('我不喜欢🥑,从沙拉里拿出来:', saladSet);

现在我们的沙拉套餐是,

我不喜欢🥑,从沙拉里拿出来: Set(3) {"🍅", "🥕", "🥒"}

让我们清理一下,吃完沙拉!

使用​clear()​方法从Set​中删除所有元素

saladSet.clear();
console.log('Finished it:', saladSet);

输出

Finished it: Set(0) {}

使用Set迭代

​Set​有一个名为values()​的方法,它返回一个​SetIterator​以获取所有值。

const houseNos = new Set([360, 567, 101]); 
console.log(houseNos.values());

输出

SetIterator {360, 567, 101}

我们可以在这上面使用foreach或for-of循环来检索值。

有趣的事实:JavaScript强调使Set​与Map​兼容。这就是为什么我们找到了两个Set​方法,​keys()​和​entries()​,就像Map一样。

由于Set​没有键,​keys()​方法返回一个SetIterator来检索值。

console.log(houseNos.keys());

输出

SetIterator {360, 567, 101}

现在尝试Map​的entries()​它返回迭代器以检索键值对。Set没有键。因此,entries()​方法返回一个SetIterator来检索 值-值对。

console.log(houseNos.entries());

输出

SetIterator {360 => 360, 567 => 567, 101 => 101}

让我们枚举

我们可以使用​forEach​和​for-of​循环枚举一个Set。

houseNos.forEach((value) => { 
	console.log(value);
});

输出

360
567
101

用for-of​

for(const value of houseNos) { 
	console.log(value);
}

Set and object

​Set​可以有任何类型的元素,甚至是对象。

const person = { 'name': 'Alex', 'age': 32 }; 
const pSet = new Set();
pSet.add(person);
console.log(pSet);

输出

毫不奇怪。Set包含一个作为对象的元素。现在让我们更改对象的属性并再次将其添加到集合中。

person.name = 'Bob'; 
pSet.add(person);
console.log(pSet);

你觉得输出怎么样?两个​person​的对象还是一个?这是输出,

​Set​是唯一元素的集合。通过更改对象的属性,我们没有更改对象本身。因此Set​不允许重复元素。

Set and Array

数组,如Set,允许向其添加和删除元素。但是Set与数组不同,它并不意味着替换数组。

数组和Set之间的主要区别是,数组允许重复元素,其中Set用于不同的元素。一些Set操作(delete)也比数组操作(shift, splice)更快。

​Set​数据结构不是数组的替代品。与数组一起设置可以解决有趣的问题。

将Set转换为数组

在许多情况下,您可能希望将Set转换为数组。事实上,这很容易!

const arr = [...houseNos];
console.log(arr);

输出

使用Set从数组中获取唯一值

Set数据结构最常见的用法是从数组中获取唯一值。

const mixedFruit = ['🍉', '🍎', '🍉', '🍈', '🍏', '🍎', '🍈',]; 
const mixedFruitSet = new Set(mixedFruit); 
console.log(mixedFruitSet);

输出

Set(4) {"🍉", "🍎", "🍈", "🍏"}

Set 操作

​Set集合​和数组​一起执行基本的集合操作非常容易,如union​(并集)、intersection​(交集)、diference​(集差)、superset​(超集)、subset​(子集)等。让我们用这两个集合来执行这些操作

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

Union

集合A和B的并集​,表示为A ∪ B,是作为A或B或两者的成员的所有项的集合。例如。{1,2,3}和{3,4,5}的并集是集合{1,2,3,4,5}。

const union = new Set([...first, ...second]);
console.log('Union:', union);

输出

Union: Set(5) {1, 2, 3, 4, 5}

Intersection

集合A和B的交集​,表示为A ∩ B,是同时属于A和B的所有对象的集合。例如,{1,2,3}和{3,4,5}的交集是集合{3}。

const intersection = new Set([...first].filter(elem => second.has(elem)));
console.log('Intersection:', intersection);

输出

Intersection: Set(1) {3}

Difference

U和A的集差​,表示U \ A,是U中所有不是A成员的成员的集合。集差{1,2,3}{3,4,5}为{1,2},反之,集差{3,4,5}{1,2,3}为{4,5}。

const difference = new Set([...first].filter(elem => !second.has(elem)));

输出

Difference: Set(2) {1, 2}

Superset

如果A的所有元素也是B的元素,则集合A是集合B的子集;B是A的超集。

const isSuperset = (set, subset) => { 
	for (let elem of subset) { 
		if (!set.has(elem)) { 
			return false; 
		} 
	} 
	return true;
}
console.log('Is Superset?', isSuperset(first, second));

输出

Is Superset? false