阅读 148

(深度好文)面试官问你知道数组去重九种方法的优缺点吗

 var arr = [1, 1, '1', '1', null, null, undefined, undefined, new String('1'), new String('1'), /a/, /a/, NaN, NaN];复制代码

双重for循环去重

优点: 

          兼容性好 

          '1'和1可以区分

缺点:

          对象不可以去重 因为对象不可以用来比较   

          NaN不可以去重

Array.prototype.unique = function () { 
    var newArr = [], 
        isRepeat,                
        len = this.length;            
    for (var i = 0; i < len; i++) {                
        isRepeat = false;                
        for (var j = 0; j < newArr.length; j++) {                    
            if (this[i] === newArr[j]) {                        
                isRepeat = true;                        
                break;                    
            }                
        }                
        if (!isRepeat) {                    
            newArr.push(this[i]);                
        }            
    }            
    return newArr;        
}复制代码

indexOf去重

优点: 

          '1'和1可以区分

缺点: 

           对象不可以去重 因为对象不可以用来比较

           NaN不可以去重

Array.prototype.unique = function() {            
    var res = [],                
    len = this.length;            
    for (var i = 0; i < len; i++) {     
        var current = this[i];                
        if (res.indexOf(current) === -1) {                    
            res.push(current);                
        }            
    }            
    return res;        
}复制代码

相邻元素去重

优点:

          '1'和1可以区分

缺点:

           对象不可以去重 因为对象不可以用来比较

           NaN不可以去重

           不能识别undefined

Array.prototype.unique = function () {            
    var newArr = [],                
    len = this.length;            
    this.sort(function(a, b) { // 改变原数组       
         return a-b;         
    });            
    for (var i = 0; i < len; i++) {                
        if (this[i] !== this[i + 1]) {           
             newArr.push(this[i]);    
        }            
    }            
    return newArr;        
}复制代码

filter

优点:

          '1'和1可以区分  

 缺点:        

           对象不可以去重 因为对象不可以用来比较                

           NaN识别不了

Array.prototype.unique = function() {            
    var res = this.filter(function(item, index, array){                
        return array.indexOf(item) === index;            
    })            
    return res;        
}复制代码

includes

优点: 

          '1'和1可以区分 

          NaN可以去重

缺点:    

          对象不可以去重 因为对象不可以用来比较        

Array.prototype.unique = function () {            
    var newArr = [];            
    this.forEach(item => {                
        if (!newArr.includes(item)) {                    
            newArr.push(item);                
        }            
    });            
    return newArr;        
}复制代码

reduce

优点:

          可以区分'1'和1

缺点:

          对象不可以区分 

          NaN不可以区分

Array.prototype.unique = function () {            
    return this.sort().reduce((init, current) => {                
        if (init.length === 0 || init[init.length - 1] !== current) {                    
            init.push(current);                
        }                
        return init;            
    }, []);        
}复制代码

对象键值对

基本思路:利用了对象的key不可以重复的特性来进行去重。

优点: 

          NaN可以去重 

          正则可以去重

 缺点:

           '1'和1不能区分 

            对象不可以去重 因为对象作为 key 会变成 [object Object]

Array.prototype.unique = function () {            
    var obj = {},                
    arr = [],                
    len = this.length;            
    for (var i = 0; i < len; i++) {                
        if (!obj[this[i]]) {                    
            obj[this[i]] = 'abc'; // 不能是 = this[i] 万一数组去重0                    
            arr.push(this[i]);                
        }            
    }            
    return arr;        
}

// 改变版本1   
Array.prototype.unique = function () {            
    const newArray = [];            
    const tmp = {};            
    for (let i = 0; i < this.length; i++) {                
        if (!tmp[typeof this[i] + this[i]]) {                    
            tmp[typeof this[i] + this[i]] = 1;                    
            newArray.push(this[i]);                
        }            
    }            
    return newArray;        
}

// 改进版本2  
Array.prototype.unique = function () {            
    const newArray = [];            
    const tmp = {};            
    for (let i = 0; i < this.length; i++) {                
        // 使用JSON.stringify()进行序列化                
        if (!tmp[typeof this[i] + JSON.stringify(this[i])]) {                    
            // 将对象序列化之后作为key来使用                    
            tmp[typeof this[i] + JSON.stringify(this[i])] = 1;                    
            newArray.push(this[i]);                
        }            
    }            
    return newArray;        
}
复制代码

Map

原理: key对应value,key和value唯一 ,任何值都可以当属性

优点:

        NaN可以去重

缺点:

        对象不可以去重

Array.prototype.unique = function () {            
    var newArr = [],            
        tmp = new Map(),
        len = this.length;            
    for (var i = 0; i < len; i++) {                
        if (!tmp.get(this[i])) {                    
            tmp.set(this[i], 1);                    
            newArr.push(this[i]);                
        }            
    }            
    return newArr;        
}

//简化版
Array.prototype.unique = function() {            
    var map = new Map()            
    return arr.filter((a) => !map.has(a) && map.set(a, 1))        
}复制代码

Set

 原理: 它类似于数组,但是成员的值都是唯一的,没有重复的值

优点: 

          NaN去重

缺点: 

         对象不可以去重

 Array.prototype.unique = function () {            
    return [...new Set(this)];        
}复制代码


你的点赞是我持续输出的动力 希望能帮助到大家 互相学习 有任何问题下面留言 一定回复


关注下面的标签,发现更多相似文章
评论