写点什么

重学 JS | Set 和 Map 是如何过滤重复值的?

用户头像
梁龙先森
关注
发布于: 2021 年 01 月 25 日
重学JS | Set和Map是如何过滤重复值的?
背景

ES6 的 Set 集合是一种包含多个非重复值的有序列表,值与值如果相同,则会自动过滤重复值。它可以用来过滤数组中的重复元素,但是 Set 集合并不是数组的子类,所以不能通过索引直接访问集合中的值,只能通过 has()检测元素是否在集合中,或者通过 size()检测集合中值的数量,同时它支持 forEach()或者遍历器来处理集合中的每个值。


Map 是多个键值对组成的有序集合,键名支持任意数据类型,同时 Map 也是不允许存在重复值,对键名会存在过滤。


那 Set 和 Map 是怎么过滤键值对的?我们通常比较值,有两种方式用“==”或者“===”。


附:对 Set 不熟的可以前往改文字看看

ES6既有Set,为何还要有Weak Set集合?

==运算符

“==”运算符在判断相等时,如果两边的变量不是同一类型,会进行强制转换。这会导致(""==false)为 true。

===运算符

“===”运算符只有在无需类型转换运算数就相等的情况下,才返回 true。其将+0 和-0 视为相等,Number.NaN 与 NaN 视为不相等。

学过 Set 和 Map 我们都知道,在这两集合中 1 和“1”是不会被过滤,且 NaN 值会被过滤,只允许存在一个。那么上述两种运算符是不符合了。

Object.is()

该用于判断两个值是否为同一值。而 Set 和 Map 集合便是用此方法进行判断,它的用法如下:

// value1:被比较的第一个值 value2:被比较的第二个值Object.is(value1,value2)
复制代码

Object.is()判断两个值是否同一值的规则如下:

  1. 都是 undefined

  2. 都是 null

  3. 都是 true 或 false

  4. 都是相同长度的字符串且相同字符串顺序排列

  5. 都是相同对象(对象同一个引用)

  6. 都是数字且

  7. 都是+0

  8. 都是-0

  9. 都是 NaN

  10. 或都是非零而且非 NaN 且为同一个值

看完它两值相等的规则,很好的满足 Set 和 Map 集合过滤重复值的需求点。

Polyfill

最后实现下 Object.is 的 Polyfill。

if(!Object.is){	Object.is = function(x,y){  	if(x===y){      // 满足上述的1~6.2和6.4点的判断      // 1/x === 1/y :判断的是+0和-0      return x!==0 || 1/x === 1/y    }else{      // 此处判断的是x和y是否都为NaN    	return x!==x && y!==y    }  }}
复制代码


至此关于类型相等可以灵活运用了。

发布于: 2021 年 01 月 25 日阅读数: 26
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
重学JS | Set和Map是如何过滤重复值的?