六种数组去重


1. 双重循环去重

function unique(arr) {
    for (var i = 0; i < arr.length; i++) {
        for (var j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) {//第一个等同于第二个,splice方法删除第二个
                arr.splice(j, 1);
                j--;
            }
        }
    }
    return arr;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

2. indexOf includes findIndex find some filter 减少内层循环去重

indexOf

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array.indexOf(arr[i]) === -1) {
            array.push(arr[i])
        }
    }
    return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

indexOf 接收元素,返回符合条件的第一个index,不存在时返回-1
includes 接收元素,返回boolean,不存在时返回false
findIndex 接收函数,返回符合条件的第一个index,不存在时返回-1
find 接收函数,返回符合条件的第一个元素,不存在时返回undefined
some 接收函数,匹配符合条件的第一个元素 返回boolean,不存在时返回false
filter 接收函数,匹配所有符合条件的元素,返回数组,不存在时返回空数组

includes

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (!array.includes(arr[i])) {
            array.push(arr[i])
        }
    }
    return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

find

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (!array.find((item) => item === arr[i])) {
            array.push(arr[i])
        }
    }
    return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

some

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (!array.some((item) => item === arr[i])) {
            array.push(arr[i])
        }
    }
    return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

3. filter代替外层循环 indexof代替内层循环

function unique(arr) {
    return arr.filter((item, index)=> {
        // filter循环到的初次见面的元素会被return,第二个同种元素的indexOf会返回第一个同种元素的index而未通过校验,不return
        return arr.indexOf(item) === index
    })
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

4. sort排序 再遍历 相邻节点比较

function unique(array) {
    var res = [];
    var sortedArray = array.concat().sort();
    var last;
    for (var i = 0, len = sortedArray.length; i < len; i++) {
        // 如果是第一个元素或者相邻的元素不相同
        if (!i || last !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        last = sortedArray[i];
    }
    return res;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

Set

function unique(array) {
   return Array.from(new Set(array));
}

function unique2(array) {
    return [...new Set(array)];
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]

5. Object 键值对

function distinct(array) {
    var obj = {};
    return array.filter(function(item, index, array){
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

JS 数组去重怎么实现。(回答 Set)如果要对对象去重怎么做。

6. 额外的知识 几个类型的相等问题 以及无法去重的情况

let str1 = '123';
let str2 = new String('123');

console.log(str1 == str2); // true
console.log(str1 === str2); // false

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 底层使用的是 === 进行判断,所以使用 indexOf 查找不到 NaN 元素
Set可以去重NaN类型, Set内部认为尽管 NaN === NaN 为 false,但是这两个元素是重复的

// 比较
var array = [1, 1, '1', '1', null, null, undefined, undefined, new String('1'), new String('1'), /a/, /a/, NaN, NaN];

Array.sort()加一行遍历冒泡 无法去重 对象 和 NaN 和 数字1
双重For循环 无法去重 对象 和 NaN
filter+indexOf 无法去重 对象 和 NaN消失
Set去重 无法去重 对象
Object 键值对去重 全部去重

参考:
ikoala大佬的如何答一道惊艳面试官的数组去重问题

大佬的测试结果
双重 for 循环 > Array.filter()加 indexOf > Array.sort() 加一行遍历冒泡 > Object 键值对去重复 > ES6中的Set去重


文章作者: 罗紫宇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗紫宇 !
  目录