JavaScript数组去重方法汇总

1.运用数组的特性

  1.遍历数组,也遍历辅助数组,找出两个数组中是否有相同的项,若有则break,没有的话就push进去。

  

//第一版本数组去重
function unique(arr){
    var  res = [],
         len = arr.length;
    for(let i = 0;i < len; i++){
        var reslen = res.length;
        for(let j = 0;j < reslen; j++){ //遍历辅助数组
            if(arr[i] === res[j]){
                break;
            }
        }
        if(j === reslen){
            res.push(arr[i]); //没有就添加进去
        }
    }
    return res;
}

  

  2.运用es5的indexOf方法

//第二版本数组去重 es5语法, IE8不能用
function unique(arr){
    var len = arr.length,
        res = [];
    for( let i = 0; i < len ; i++){
        let val = arr[i];
        if(res.indexOf(val) === -1){ //找不到返回-1
            res.push(arr[i]);
        }
    }
    return res;
}

  

  3.如果数组已经排好序

function unique(arr){
    var len = arr.length;
        last,
        res = [];
    for(let i = 0;i < len; i++){
        let val = arr[i];
        if(val !== last){ //用last存储上一次的值
            res.push(val);
        }
        last = val;
    }
    return res;
}

  

  4.留一个接口,传一个参数判断数组是否已经排好序

function unique(arr, isSort){
    var len = arr.length,
        res = [],
        last;
    if(isSort !== 'boolean'){
        isSort = false;
    }
    for(let i = 0;i < len; i++){
        var val = arr[i];
        if(isSort){
            if(!i || val!== last){
                res.push(val);
            }
            last = val;
        }else{
            if(res.indexOf(val) === -1){
                res.push(val);
            }
        }
    }
    return res;
}

  5.如果有特殊需求的话,留一个接口,更灵活

function unique(arr, isSort, fn){
    var res = [],
        len = arr.length,
        newArr = [],
        last;
    for(let i = 0;i < len; i++){
        var val = arr[i],
            com = fn ? fn(val, i, arr) : val;
        if(isSort){
            if(!i || com === last){
                res.push(val);
            }
            last = com;
        }else if(fn){
            if(newArr.indexOf(com) === -1){
                newArr.push(com);
                res.push(val);
            }
        }else if(res.indexOf(val === -1)){
            res.push(val);
        }
    }
    return res;
}

  6.用内部 filter 方法优化

function unique(arr){
    var res = [],
    res = arr.filter(function(item, index, arr){
        return res.indexOf(item) === index;  //返回true则添加到数组res,否则不添加
    });
    return res;
}

2.运用对象的特性

  1.第一种方法

function unique(arr){
    var obj = {},
        res = [],
    res = arr.filter(function (item, index, aee){
        return obj.hasOwnProperty(item) ? false : (obj[item] = true);
    });
    return res
}

  注意: 有一个Bug,var  = [ 1,1,"1",2],不能识别number类型的和string类型,添加到对象中都会转化为string。

  2.第二种方法

 

function unique(arr){
    var obj = {},
        res = [],
        len = arr.length;
    res = arr.filter(function (item, index, arr){
        return obj.hasOwnProperty(typeof item + item) ? false : (typeof item + item) = true;  
    });
    return res;
}

  注意:这里也有bug,因为typeof的返回类型,检测不了对象。

  3.第三种方法

  运用json方法进行优化。

function unique(arr){
    var obj = {},
        res = [],
        len = arr.length;
    res = arr.filter(function (item, index, arr){
        return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (typeof item + JSON.stringify(item)) = true;
    })
    return res;
}

3.ES6中的Set()对象

function unique(arr){
    return [...new Set(arr)];
}