ES6+ Set
1. 前言
上一节,我们对 ES6 新的数据结构做了简要的介绍,并没有深入的学习。这节我们将深入地学习 Set 数据结构,了解 Set 的存储方式,可以让我们更深入地理解 Set 数据结构。
2. 基本用法
Set
不像数组可以用索引去查找存储的数据,所以 Set
没有修改操作。Set
存储的数据都是唯一的,而且可以是任意类型的数据。
var set = new Set([, , ])
console.log(set) // Set(3) {1, 2, 3}
// 创建一个空的 Set 实例
var set = new Set() // Set(0) {}
// 添加数据
set.add('es6') // Set(1) {"es6"}
// 还可以链式添加数据
set.add('imooc').add({age: '7'})
cosnole.log(set) // 如下图
上面的例子中,对 Set
实例添加元素,可以添加引用类型数据。Set
的存储方式是以对象的形式存放的,所以 Set
的本质也就是一个对象,它继承 Object,我们可以通过原型链( __proto__
)找到最上层是 Object。
// 创建一个带默认值的 Set 实例
var set = new Set([, , ]);
// delete 删除数据: 删除指定的数据,或者清空数据
console.log(set.delete());
// set.size 可以统计多少条数据,类似数组中的length属性
console.log(set.size); // 2
// clear 会清空Set实例
console.log(set.clear()); // Set(0) {}
// has 方法可以查看某个元素是否包含在 Set 实例中
console.log(set.has('a')); // false
console.log(set.has()); // true
2. 案例:数组去重
在 ES5 中数组去重的方法很多,一种是使用 for 循环来对数组中的项进行一一验证,另一种是比较高效的方法就是借助对象的键是唯一的特性进行去重操作。下面我们来实现这两种方法,并对比 Set 方式去重。
2.1 使用 for 循环去重
function unique(arr) {
const newArr = []
for (let i = ; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -) {
newArr.push(arr[i])
}
}
return newArr
}
这种方法比较简单也是最常见的方法,虽然这里只有一次循环,但是 indexOf
的查询也是有时间复杂度的,所以不能单纯地认为这里的时间复杂度是 n。另外,由于 indexOf
存在一些缺陷这里也可以使用 @L_502_1@ 进行替换。
function unique(arr){
const newArr = [];
const hash = {};
for(var i=; i<arr.length; i++){
if(!hash[arr[i]]){
hash[arr[i]] = true;
newArr.push(arr[i]);
}
}
return newArr;
}
上面的代码时间复杂度是 n,只需要对数组进行一次循环即可。把循环的元素存放在 hash 表中来记录不重复的元素。如果 hash 表中找不到对应的值则在 hash 表中添加一个记录,并把该元素 push 到数组中。这样的方式时间复杂度为 n,但是维持一个 hash 表需要更多的空间。
2.3 使用 Set 方法去重
function unique(arr) {
return [...new Set(arr)]
}
上面的代码可以看出,上节我们学习了 Set 和数组直接的转换,可以使用 ...
语法展开 Set 实例就可以得到数组。当然还可以使用 Array.from()
方法把 Set 数据结构转化为数组。这种方式在低版本浏览器是不能运行的。
其实上面三种方式都有一定的缺点:
3. Set 的扩展方法
Set 实例上的数据可以使用 forEach
进行遍历:
var set = new Set(['a', 'b', 'c'])
set.forEach((item) => {
console.log(item)
})
// a
// b
// c
虽然在 Set 数据结构中没有索引的概念,但是 Set 提供了三个方法用于我们去遍历 Set 数据结构。
var set = new Set(['a', 'b', 'c'])
set.keys(); // SetIterator {"a", "b", "c"}
set.values(); // SetIterator {"a", "b", "c"}
set.entries(); // SetIterator {"a" => "a", "b" => "b", "c" => "c"}
for(var [key, value] of set.entries()) {
console.log(key, value)
}
// a, a
// b, b
// c, c