数组去重,看这一篇就够了!!!!

前言

关于JS数组去重的一些解决方案,今天也是查到了这个点,废了一天时间,总结了以下方法,在考虑全面的情况下,数组去重的实现,针对于NaN,undefined,{},都有实现的方式,下面是具体实现步骤。

实现大全
基础版

测试数组

var array = [1, 1, ‘’, ‘’, ‘e’, ‘e’, true, ‘true’, true, false, false, ‘false’, undefined, ‘undefined’, undefined, null, ‘null’, null]

  • ES5的for方法
function uniqueUseFor(array) {
        var temp = []; //一个临时数组

        //遍历当前数组
        for (var i = 0, j = array.length; i < j; i++) {
            //很直白,新数组内判断是否有这个值,没有的情况下,就推入该新数组
            temp.indexOf(array[i]) === -1 ? temp.push(array[i]) : '';
        }
        console.log(temp)
        return temp;
    }
    uniqueUseFor(array)

在这里插入图片描述

  • ES5内置的forEach方法
function uniqueUseForEach(array){
        // 传入值必须存在,且长度小于等于1的时候直接返回数组
        if(array&&array.length<=1){
            return array
        }else{
            var tmp = [];
            // 遍历当前数组
            array.forEach(function(value,index){
                tmp.indexOf(value)===-1?tmp.push(value):"";
            })
            console.log(tmp)
            return tmp;
        }
    }
    uniqueUseForEach(array)

在这里插入图片描述

  • ES6内置的for-of方法
function uniqueUseForOf(array){
        const tmp = [];
        // 传入值必须存在,且长度小于等于1的时候直接返回数组
        if(array&&array.length<=1){
            return array
        }else{
            // 遍历当前数组
            for(let x of array){
                tmp.indexOf(x) === -1?tmp.push(x):"";
            }
        }
        console.log(tmp)
        return tmp
    }
    uniqueUseForOf(array)

在这里插入图片描述

进阶版

包含NaN,undefined,null

测试数组

let array = [1, 1, ‘true’, true, true, 5, ‘F’, false, undefined, null, null, undefined, NaN, 0, 1, ‘a’, ‘a’, NaN, ‘NaN’]

    function uniqueUseNotAllEqual(array) {
        var tmp = [] //一个临时数组
        mark = true; //标识位

        // 遍历当前数组
        for (var i = 0, j = array.length; i < j; i++) {
            // 标识符的作用就是用来判断是否存在NaN,第一次找不到保留到新数组中
            // 然后标识位置改为false是为了再次找到的时候不推入数组
            if (array[i] !== array[i]) {
                // 这里的不等特性,也可以用isNaN判断[ES6]
                mark && tmp.indexOf(array[i]) === -1 ? tmp.push(array[i]) : "";
                mark = false
            } else {
                tmp.indexOf(array[i]) === -1 ? tmp.push(array[i]) : "";
            }
        }
        console.log(tmp)
        return tmp;
    }
    uniqueUseNotAllEqual(array)

在这里插入图片描述

  • ES6内置Array.prototype.includes()大法
    function uniqueCompareUseIncludes(array) {
        // 传入值必须存在,且长度小于等于1的时候直接返回数组
        if (array && array.length <= 1) {
            return array
        } else {
            let tmp = [];   //一个临时数组
            // 遍历当前数组
            for (let x of array) {
                // includes()方法用来判断当前数组是否有指定包含的值,如果有返回true没有返回false
                tmp.includes(x) ? "" : tmp.push(x)
            }
            console.log(tmp)
            return tmp
        }
    }
    uniqueCompareUseIncludes(array)

在这里插入图片描述

[es6] Array.from或扩展运算符[…]结合set大法
/*
* 知识点
* 1.Set的值具有唯一性,内部会自动===比较,
* 是可迭代对象(iterable),有点特殊的是NaN这货虽然有不全等的特性,
* 在Set里面认为是相同的,所以只能有一个
* 2.Array.from和…可以把类似数组【nodelist or arguments】
* 这类可迭代的对象中转为一个标准的数组
*/

// Array.from+Set的方法
let arr = Array.from(new Set([1, 1, 'true', true, true, 5, 'F', false, undefined, null, null, undefined, NaN, 0, 1, 'a', 'a', NaN, 'NaN']))
console.log(arr)

// ... 扩展运算符 +Set的方法
let arrTow = [...new Set([1,1,'true',true,true,5,'F',false, undefined, null,null,undefined, NaN, 0, 1, 'a', 'a', NaN,'NaN'])]
console.log(arr)
高阶版

包含{},NaN,undefined,null

测试数组

let array = [1, 1, ‘true’, true, true, 5, ‘F’, false, undefined, null, null, undefined, NaN, {}, {}, ‘{}’, 0, 1, ‘a’, ‘a’, NaN]

  • ES5 fro-in + call +for 方案
    function uniqueUseForIn(array) {
        var tmp = [];
        var emptyObjectMark = true; //标识位
        var NaNObjectMark = true;   //标识位
        // 判断空对象
        function isEmptyObject(object) {
            if (Object.prototype.toString.call(object) === "[object Object]") {
                for (var i in object) {
                    // 存在属性和方法,则不是空对象
                    return false
                }
                return true;
            } else {
                return false
            }
        }

        // 传入值必须存在,且长度等于小于1的时候返回数组
        if (array && array.length <= 1) {
            return array
        } else {
            // 遍历当前数组
            for (var i = 0, j = array.length; i < j; i++) {
                //标识位的作用就是用来判断是否存在NaN和空对象,第一次找到保留到新数组中
                //然后标识位置改为false是为了再次找到的时候不推入数组
                if (isEmptyObject(array[i])) {
                    emptyObjectMark && tmp.indexOf(array[i]) == -1 ? tmp.push(array[i]) : "";
                    emptyObjectMark = false
                } else if (array[i] !== array[i]) {
                    NaNObjectMark && tmp.indexOf(array[i])  == -1 ? tmp.push(array[i]) : "";
                    NaNObjectMark = false
                } else {
                    tmp.indexOf(array[i]) == -1 ? tmp.push(array[i]) : "";
                }
            }
            console.log(tmp)
            return tmp;
        }
    }
    uniqueUseForIn(array)

在这里插入图片描述

拓展版

多维数组扁平化再去重

测试数组

let array = [1, 1, [[‘true’, true, true, [5, ‘F’], false], undefined], null, null, [undefined, NaN, {}], {}, ‘{}’, 0, 1, ‘a’, ‘a’, NaN]

/*
*   知识点
*       数组扁平化用了递归实现
*       代码也考虑了默认参数,防止不传递参数的时候报错
*       ES5for-in + call + for +递归扁平化方案
*/
    function uniqueArrayWithFlattern(array) {
        var _array = array || []
        function isEmptyObject(object) {
            if (Object.prototype.toString.call(object) === "[object Object]") {
                for (var i in object) {
                    return false
                }
                return true
            } else {
                return false
            }
        }

        // 遍历查询判断,扁平化数组 
        function forArrayFlattern(arr) {
            // console.log("fenqian",arr)
            for (var m = 0, n = arr.length; m < n; m++) {

                if (Array.isArray(arr[m])) {
                    // console.log("分割2",_array.splice(m,1))
                    // console.log("分割1",_array)
                    var _tmpSpliceArr = _array.splice(m, 1)[0];
                    // console.log("分割完",_tmpSpliceArr)
                    _array = _array.concat(_tmpSpliceArr)
                    // console.log("==========================",_array)

                    return forArrayFlattern(_array)
                }
            }
            return uniqueArr(_array)
        }

        // 传入值必须存在,且长度小于等于1的时候直接返回数组
        if (_array && _array.length <= 1) {
            return _array
        } else {
            if (Array.isArray(_array)) {
                return forArrayFlattern(_array)
            } else {
                return _array
            }
        }

        // 数组去重
        function uniqueArr(_array) {
            var tmp = [];
            var emptyObjectMark = true;
            var NaNObjectMark = true;

            // 遍历当前数组
            for (var a = 0, b = _array.length; a < b; a++) {
                if (isEmptyObject(array[a])) {
                    emptyObjectMark && tmp.indexOf(_array[a]) == -1 ? tmp.push(_array[a]) : ""
                    emptyObjectMark = false
                } else if (_array[a] !== _array[a]) {
                    NamedNodeMap && tmp.indexOf(_array[a]) == -1 ? tmp.push(_array[a]) : ""
                    NamedNodeMap = false
                } else {
                    tmp.indexOf(_array[a]) == -1 ? tmp.push(_array[a]) : ""
                }
            }
            console.log(tmp)
            return tmp
        }
    }
    uniqueArrayWithFlattern(array)

在这里插入图片描述
详细了解移步JS数组去重!!!一篇不怎么靠谱的"深度"水文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值