数组去重的几种方法

  • 1.遍历数组法

这是最简单的数组去重方法,实现思路:新建一新数组,传入要去重的数组,遍历该数组,若值不在新数组中则加入该数组;需要注意点:判断值是否在数组的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,示例如下:

function removeDup(arr) {
    let new_arr = [];
    arr.forEach((val) => {
        if(new_arr.indexOf(val) === -1){
            new_arr.push(val);
        }
    });
    return new_arr;
}
  • 2.对象键值对法

思路:新建一对象以及数组,遍历传入的数组,判断值是否为js对象的键,若不是则新增键值,并放入数组中;需要注意的地方:判断是否为js对象键时,会自动对传入的键toString();

    function removeDup2(arr) {
        let obj = {},
            new_arr = [],
            val,
            type;
        for(let i = 0, len = arr.length; i < len; i+=1) {
            val = arr[i];
            type = typeof val;
            if(!obj[val]) {
                obj[val] = [type];
                new_arr.push(val);
            }else if(obj[val].indexOf(type) === -1) {
                obj[val].push(type);
                new_arr.push(val);
            }
        }
        return new_arr;
    }
缺点:无法真正区分两个对象,如:`{a:1}`和`{a: 2}`,因为typeof结果都是`"object"`,可用`JSON.stringify()`来解决;
es6优化后如下
    function unique(array) {
        let obj = {};
        let type;
        return array.filter((item, index, array) => {
            type = typeof item + JSON.stringify(item);
            return obj.hasOwnProperty(type) ? false : (obj[type] = item);
        } )
    }
    // 可去除undefined, NaN, Object重复项
  • 3.排序后相邻去除法


    思路:首先将要去重的数组使用sort方法排序后,相同的值就会排在一起,然后就可以只判断当前元素与上一个元素是否相同,若不同则添加进去;

        function unique(array) {
            let res = [];
            let sortedArray = array.slice(0).sort();//先排序
            let seen;//记录上一个元素
            for(let i = 0, len = sortedArray.length; i < len; i++) {
                let current = sortedArray[i];
                if(!i || seen !== current) {
                    res.push(current);
                }
                seen = current;
            }
            return res;
        }

    优化:可传入一个isSorted参数,表明该数组是否已排序,如果为true,那么就判断相邻元素是否相同;如果为false,则使用indexOf判断:

        function unique(array, isSorted) {
            let res = [];
            let seen;//记录上一个元素
            for(let i = 0, len = array.length; i < len; i++) {
                let current = array[i];
                if(isSorted) {
                    if(!i || seen !== current) {
                        res.push(current);
                    }
                    seen = current;
                }else if(res.indexOf(current) === -1) {
                    res.push(current);
                }
            }
            return res;
        }

    再优化:想象一个场景,你需要对数组的每一项进行一些处理,但又不想再遍历一次,那么可添加第三个参数itreatee,接受一个函数作为处理函数;

        function unique(array, isSorted, iteratee) {
            let res  = [];
            let seen = [];
            for(let i = 0, len = array.length; i < len; i++) {
                let value = array[i];
                let computed = iteratee ? iteratee(value, i, array) : value;
                if(isSorted) {
                    if(!i || seen !== computed) {
                        res.push(value);
                    }
                    seen = computed;
                }else if(iteratee) {
                    if(seen.indexOf(computed) === -1) {
                        res.push(value);
                        seen.push(computed);
                    }
                }else if(res.indexOf(value) === -1) {
                    res.push(value);
                }
            }
            return res;
        }
  • 4.ES6,Set和Map去重

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

    //扩展运算符简化
    let unique = (arr) => [...new Set(arr)];

    //使用Map
    function unique(array) {
        let seen = new Map();
        return arr.filter((a) => !seen.has(a) && seen.set(a, 1));
    }

墨白
90 声望0 粉丝

菜鸟一个