javaScript数组去重八种方法大集合

数组去重在前端笔试和面试中出现频率极高,下面为大家总结了常用常见的方法。

一,利用ES6 Set去重

//Array.from()写法
function unique(arr) {
   return Array.from(new Set(arr));
}

console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, {…}, {…}

函数部分可以简写成下面两种

//数组的扩展运算符(...)
function unique(arr) {
    return [...new Set(arr)];
}

//箭头函数写法
var unique = (arr) => [...new Set(arr)];

总结:NaN能去重,{}不能去重;

二,利用ES6 Map去重

function unique(arr) {
    const m = new Map();
    return arr.filter(function (item) {
        //"&&"遇假返回,若都为真返回最后一个
        return !m.has(item) && m.set(item, true);
    });
    //箭头函数写法
    // return arr.filter((item) => !m.has(a) && m.set(item, true));
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]))
//111, "str", true, undefined, null, NaN, {…}, {…}

总结:NaN能去重,{}不能去重;

三,利用双层for循环

第一种:使用数组splice()方法

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;
}

console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}

第二种:使用数组push()方法

function unique(arr) {
    // newArr用来存储结果
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < newArr.length; j++ ) {
            if (arr[i] === newArr[j]) {
                break;
            }
        }
        // 如果arr[i]是唯一的,那么执行完循环,j等于newArr.length
        if (j === newArr.length) {
            newArr.push(arr[i])
        }
    }
    return newArr;
}

console.log(unique([111,111,"str","str",true,true,undefined,undefined,null,null,NaN,NaN,{},{}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}

总结:两种方法结果都是一样,本质通过遍历对数组每一项进行三等判断,此方法NaN和{}不能去重。注意,若进行的是双等判断,会直接将所有null删除。

四,利用数组方法indexOf()去重

利用indexOf简化内层循环,判断新数组中是否存在了当前元素,不存在则通过push()方法将当前元素追加到新数组中。

function unique(arr) {
    //newArr用来储存数据
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, NaN, {…}, {…}

总结:此方法NaN和{}不能去重

五,利用数组方法sort()排序后去重

利用数字的sort()方法先对数组进行排序,这样重复项就变成了相邻项,我们只需判断数组当前项是否与前一项相同即可,不同则利用push()方法追加到新数组中。

第一种:给新数组第零项赋初值(原始数组第零项)

function unique(arr) {
    arr = arr.sort();
    var newArr = [arr[0]];//用newArr来储存数据,并先将arr[0]存在数组中
    for (var i = 1; i < arr.length; i++) {//i从1开始
        if (arr[i] !== arr[i - 1]) {//判断当前项是否等于前一项
            newArr.push(arr[i]);
        }
    }
    return newArr;
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined

第二种:定义临时变量储存数组前一项(有一点点难理解)

function unique(arr) {
    arr = arr.sort();
    var newArr = [];//newArr用来储存数据
    var temp;//temp用来储存前一项
    for (var i = 0; i < arr.length; i++) {//i从0开始
        if (!i || temp !== arr[i]) {//判断当前项是否等于前一项
            newArr.push(arr[i]);
        }
        temp = arr[i];
    }
    return newArr;
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined

总结:此方法比起indexOf效率高,NaN和{}不能去重

六,利用数组方法filter去重

filter()返回原始数组中执行callback函数后为true的项,不满足会直接跳过,filter()不会改变原始数组。

第一种:使用filter()+indexOf()

function unique(arr) {
    return arr.filter(function (item, index, arr) {
        //过滤条件:当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
        return arr.indexOf(item) === index;
    });
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, {…}, {…}

第二种:使用filter()+sort()

function unique(arr) {
    return arr.sort().filter(function(item, index, arr){
        //判断数组当前项和前一项是否相等,不等为true
        return !index || item !== arr[index - 1];
    });
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, NaN, NaN, {…}, {…}, null, "str", true, undefined

总结:使用filter()+indexOf(),所有的NaN会直接被删除,{}不能去重;使用filter()+sort()NaN和{}不能去重。

七,利用数组方法includes()去重

includes()方法可以判断数组是否包含指定的值,遍历原始数组判断新数组中是否包含原始数组中的每一项,不包含则使用push()方法追加到新数组中。

function unique(arr) {
    var newArr = [];//newArr用来储存数据
    for (var i = 0; i < arr.length; i++) {
        if (!newArr.includes(arr[i])) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}

console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, {…}, {…}

总结:此方法NaN能去重,{}不能去重

八,利用对象方法hasOwnProperty()方法去重

我们定义一个空的 Object 对象,利用hasOwnProperty()方法判断对象是否存在该属性,不存在则添加,存在则跳过,比如有 Object[key1] = true,在判断另一个值的时候,如果 Object[key2]存在的话,就说明该值是重复的。

function unique(arr) {
    var obj = {};
    return arr.filter(function(item, index, arr){
        //假如我们认为数字和其该数字的数字字符串是不同的,则需让(typeof item + item)整体作为Object的key
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    });
}
console.log(unique([111, 111, "str", "str", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}]));
//111, "str", true, undefined, null, NaN, {…}

若将对象obj申明在全局,最后我们再输出,可以清楚的看到里面的属性和值

javaScript数组去重八种方法大集合_第1张图片

总结:几乎所有都能去重

笔者是一个js初学者,欢迎各位大佬对内容进行指点。

你可能感兴趣的:(javaScript,数组去重,ES6,Array)