[个人博客]:(https://github.com/zenglinan/blog)
如果对你有帮助,欢迎star。
数组去重
数组去重是经常前端遇到的场景, 去重的办法也有很多, 然而都各有优缺点, 需要根据场景选择合适的方案。
1. 利用对象
将数组的元素存为对象的键, 这样去判断另一个元素是否重复的时候, 只需用hasOwnProperty
判断对象是否有该键, 将元素作为对象的键值存入对象的时候, 对象会将同样的键合为一个, 脏活累活都帮我们干了~
let arr = [1,2,1,'1',{a:1},{a:2},null,null,NaN,NaN,3,4]
let tmp = {}
arr.filter((item) => {
return tmp.hasOwnProperty(item) ? false : (tmp[item] = true)
})
这个方法兼容性好, 但是 1 和 "1" 会被当做重复的key, 所以我们存的时候可以加上类型
let arr = [1,2,1,'1',{a:1},{a:2},null,null,NaN,NaN,3,4]
let tmp = {}
arr.filter((item) => {
return tmp.hasOwnProperty(toString.call(item)+item) ? false : (tmp[toString.call(item)+item] = true)
})
到这里已经可以区分 1 和 "1" 了, 但是还有个问题: 对于对象无法做到区分
比如 {a: 1} 和 {a: 2}, toString.call(item)+item 都会显示为 [object Object][object Object], 所以这里用 JSON.stringify 对元素序列化一下
let arr = [1,2,1,'1',{a:1},{a:2},null,null,NaN,NaN,3,4]
let tmp = {}
arr.filter((item) => {
let serialized = JSON.stringify(item)
return tmp.hasOwnProperty(toString.call(item)+serialized) ? false : (tmp[toString.call(item)+serialized] = true)
})
至此, 所有类型都可以去重了
Set
Set 是ES6新推出的内置构造函数, Set 对象允许你存储任何类型的唯一值, 听起来, 这个简直太匹配数组去重了!
这里我们用 new Set(arr) 即可去重, 然后用...取出 new Set(arr) 返回的数组中的元素, 放入一个新数组返回。
var newArr = [...new Set(arr)]
缺点: 兼容性稍微差点, 无法去重两个一模一样的对象