你可能问,都2021年了,咋还在讨论Set基础知识?这不是Vue 3.0来了么,2021年就可以上生产了,Vue 2.0可以遍历Set,但是不支持响应式,现在3.0支持Set的响应式了,你说要不要开始学呢?
废话不说,跟数组做个对比。
Set优势方面
Set | 数组 | |
---|---|---|
希望成员唯一 | 本身就是 | 需要排重 |
添加元素可链式操作 | 能 | 不能 |
根据值删除指定元素 | 简单 | 复杂 |
Set劣势方面
Set | 数组 | |
---|---|---|
有序号下标 | 无 | 有 |
找出第N个元素 | 复杂 | 简单 |
原排序位置修改元素 | 无法直接修改,只能另定义Set重新存储 | 可以简单做到 |
数组的诸多方法 | 没有 | 有 |
Set无所谓优劣方面
Set | 数组 | |
---|---|---|
长度 | .size得出 | .length得出 |
不考虑排序前提下修改元素 | 删除旧值,添加新值 | 查出下标,重新赋值 |
Set怎么判断成员唯一性
Set内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),但区别是向Set加入值时认为NaN等于自身,而精确相等运算符认为NaN不等于自身。
Set的原生属性
- size,长度
Set的操作方法
-
.add(value):添加某个值,返回 Set 结构本身。所以可以链式操作。
-
.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。这就比数组要牛逼,数组想删除特定值,必须先查出它的下标。
-
.has(value):返回一个布尔值,表示该值是否为Set的成员。相当于数组的
arr.includes(value)
。 -
.clear():清除所有成员,没有返回值。相当于数组的
arr.length = 0
。
Set的遍历方法
- .keys():返回键名的遍历器
事实上Set的遍历方法都是模仿自Map,但是由于Set解构简单,所以这些方法都比较废。
比如.keys()跟.values()得到的结果永远一样,因为Set没有下标一说,键名就是键值。
如果打算遍历遍历器,倒不如用forEach直接遍历Set自身。
- .values():返回键值的遍历器。
不多说。
- .entries():返回键值对的遍历器
[...new Set([{},3,'5']).entries()]
// 得到
//0: (2) [{}, {}]
//1: (2) [3, 3]
//2: (2) ['5', '5']
这种数组有什么意义呢?可见.entries()实用价值也不大。
- .forEach():使用回调函数遍历每个成员
Set的唯一的一个有实用价值的遍历方法,由于键名就是键值,所以遍历起来比数组更简单,根本无需考虑下标。
Set的使用场合
-
储存不重复的数据。当添加重复数据的时候会存不上,依旧返回之前的Set。
-
实现数组去重。
[...new Set([3,4,4,4,4,5])]
得到[3,4,5]
-
只打算增和删元素,不打算改元素,或者打算改元素但不在乎排序(或是原本就希望用先删后增来实现改),可以用Set。
-
很容易地实现并集(Union)、交集(Intersect)和差集(Difference)
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集,原理是从Set a里找Set b里也有的元素
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// (a 相对于 b 的)差集,原理是从Set a里找Set b里没有的元素
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
Vue 3拿Set当data存储列表数据是否适合?
Vue 3允许拿Set当data,所以可以在发挥Set优势的场合使用Set,通常用于业务代码,比如排重等,处理之后也支持在模板渲染。不过,服务器发回的对象数组就没必要特意转成Set了,因为我们要对这个对象数组进行复杂操作,Set对比并不擅长。
数组转Set
数组直接当参数传入new Set()即可。
Set转数组
最优雅的方式是解构:[...new Set([2,3,4,5])]
网友评论