数组去重的思考

  27 Feb 2017


数组去重的思考


数组去重

数组去重老生常谈,面试必问吧基本上,最近总结下数组去重的一些方法。

双层循环

最原始的方法

var array = [1, 2, 3, 2, 4, 3]

function unique(array) {
    var resArr = [];//用来存储结果
    for (var i = 0; i < array.length; i++) {
        for (var j = 0; j < resArr.length; j++) {
            if (array[i] === resArr[j]) {
                break;
            }
        }
        if (j === resArr.length) {
            resArr.push(array[i])
        }
    }
    return resArr
}

unique(array) //[1, 2, 3, 4]

外层循环array 里面循环resArr,相等跳出,不相等的话满足j===resArr.length push进去。此方法逻辑简单,兼容性好~


indexOf

用indexOf简化内层的循环

var array = [1, 2, 3, 2, 4, 3]
function unique(array) {
    var resArr = [];//用来存储结果
    for (var i = 0; i < array.length; i++) {
      if(resArr.indexOf(array[i])===-1){
          resArr.push(array[i])
        }
    }
    return resArr
}

unique(array) //[1, 2, 3, 4]


排序后去重

如果我们先将数组排序,值相同的元素就会被排在一起,我们只要判断前后元素是否相等就可以进行去重了

let array = [1, 2, 3, 2, 4, 3]

function unique(array) {
    let sortedArray = array.sort()
    let resArr = [];//用来存储结果
    for (var i = 0; i < sortedArray.length; i++) {
        if (sortedArray[i]!==sortedArray[i+1]) {
            resArr.push(sortedArray[i])
        }
    }
    return resArr
}

unique(array) //[1, 2, 3, 4]



filter

ES5 提供了filter方法,我们可以用来简化外层循环

unique(array) //[1, 2, 3, 4]

let array = [1, 2, 3, 2, 4, 3]

function unique(array) {
    let resArr = array.filter((item, index, array) => {
        return array.indexOf(item) === index
    })
    return resArr
}

unique(array) //[1, 2, 3, 4]

//排序去重

function unique(array) {
    return resArr = array.sort().filter((item, index, array) => {
        return array[index-1] !== item
    })
}


Object 键值对

这种方法是利用一个空的 Object 对象,我们把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。

let array = [1, 2, 3, 2, 4, 3,'1']
function unique(array) {
    let obj = {};
    return array.filter(function(item, index, array){
        return obj.hasOwnProperty(item) ? false : (obj[typeof item + item] = true)
    })
}

unique(array) //[1, 2, 3, 4,'1']

ES6 Set Map 去重

ES6提供的新的数据结构Set,Map在数组去重中的用法

let array = [1, 2, 3, 2, 4, 3]

function unique(array) {
   return Array.from(new Set(array))
}
unique(array) //[1, 2, 3, 4]

简化下

let array = [1, 2, 3, 2, 4, 3]

function unique(array) {
   return [...new Set(array)]
}
unique(array) //[1, 2, 3, 4]

let array = [1, 2, 3, 2, 4, 3]

let unique=(arr)=>[...new Set(array)]

unique(array) //[1, 2, 3, 4]

使用Map

let array = [1, 2, 3, 2, 4, 3]

function unique(array) {
   const map1=new Map()
   return array.filter((item)=>!map1.has(item)&&map1.set(item,'a'))
}
unique(array) //[1, 2, 3, 4]

特殊类型比较

如果数组里含有 null, undefined, NaN, Object 去重结果会如何

console.log(null == null); // true
console.log(null === null); // true

console.log(undefined == undefined); // true
console.log(undefined === undefined); // true

console.log(NaN == NaN); // false
console.log(NaN === NaN); // false

console.log(/a/ == /a/); // false
console.log(/a/ === /a/); // false

console.log({} == {}); // false
console.log({} === {}); // false

indexOf 底层还是使用 === 进行判断,因为 NaN ==== NaN的结果为 false,所以使用 indexOf 查找不到 NaN 元素 Set 认为尽管 NaN === NaN 为 false,但是这两个元素是重复的。 优化后的键值对方法去重可以全部去重。