之前写过一篇《数组去重》。
在不断学习中,发现还有去重的方法。
数组去重方法6:
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice', 0]; var namesDelDulp = names.reduce(function(dul, name) { if (!~dul.indexOf(name)) dul.push(name) return dul; }, [])
利用ES6中新增的数组函数reduce,(关于reduce具体用法的,可以参见Array.prototype.reduce()),reduce接收两个参数,一个函数和一个函数第一个参数的初始化的值,我们这里是为形参dul初始化一个默认值为[]空数组,然后还是利用indexOf进行判断,至于~,按位取反运算符,是利用二进制数据来为0和1取反的,简单理解就相当于给当前数值+1再取反,~-1 == 0, ~1==-2,!~dul.indexOf(name),就可以判断dul中如果不存在name,就将name存入dul。
最后返回dul,达到去重的目的。
数组去重方法7:利用数组的过滤方法
var names = ['Tiff', 0, 'Alice', 'Bob', 'Tiff', 'Bruce', 'Alice', 0]; var arr = names.filter(function(name, index) { return names.indexOf(name) == index })
过滤的条件为 names.indexOf(name) == index,即在当前names中查找name,如果只有一个该元素,那么其取到的index必然相等。
在前面一篇《数组去重》的文章里,利用过Set数据结构去重,这里再利用一次Map数据结构吧
var names = ['Tiff', 0, 'Alice', 'Bob', 'Tiff', 'Bruce', 'Alice', 0]; let map = new Map(); names.forEach(function(item){ map.set(item, item) }) const newNames = [...map.values()]
所利用的也就是把数组的值既当键又当值的传入map结构,那么相同的值会覆盖,再返回为数组时,就会去掉重复的了。
这里关于map.values还有另外一种处理方式,就是数组Array新增的方法from,也能达到相同的目的。
const newNames = Array.from(map.values())
想到这个方法的时候,我突然明白,在前面利用hash做数组去重,所产生的一点缺点,其实也可以这么解决
const names = ['Tiff', 0, 'Alice', 'Bob', 'Tiff', 'Bruce', 'Alice', 0, false]; var hash = {}, arrnew = [] names.forEach(function (item, index) { hash[item] = item; }) for(let i in hash ){ arrnew.push(hash[i]) } console.log(arrnew)
原理其实跟利用map去重一样,将数组的值当做键传入对象当中,相同的键必然只有一个值,所以再取回的时候,就能够去重了。但是这里,又产生了另外一个问题,就是如果数组中的值并不是常规的基本数据类型值的话,是不能够作为对象的值的,所以这仍然不是一个完美解决方案。
备注:利用到Array的方法的去重,都可以先调用一次map,或者利用Array.from(arr, item=> item || 0),将所有falthy值改为相同的falthy值,从而达到只保留一个falthy值的目的。