数组去重的方法都有哪些?

63 阅读4分钟

前言

数组去重已经成为面试过程中很常见的笔试题目了,在过去的2023年十次面试笔试题当中,都占了九成那么多,这时候我们更要掌握并且懂的灵活运用,先从简单后突破原理再展开讲个普通的例子,再结合业务展开说。感兴趣的朋友们可以接着往下看。

数组去重

为何数组去重?

给你一串数据,数组里面包含重复的数组和非数字,对数组去重,将重复的元素去掉,从而得到一串唯一的数组。数组形式如下所示。

const arr = [
        1,
        2,
        2,
        "abc",
        "abc",
        true,
        true,
        false,
        false,
        undefined,
        undefined,
        NaN,
        NaN
];

实现方法

关于数组去重实现方法有很多,这里将介绍三种方法。

方法一:Set

先来说一种最简单直接的 API方法,代码如下所示:

const result = Array.from(new Set(arr));
console.log(result);
// [ 1, 2, 'abc', true, false, undefined, NaN ]

Set中的元素都是不重复的,Set对象仅能存储不同的值,因此达到去重的效果。

方法二:forEach() 结合 includes()

forEach方法用来遍历数组,includes方法用来检测数组是否有某个值。实现代码如下。

function removeNumber(arr) {
        const newarr = [];
        arr.forEach((element) => {
            if (!newarr.includes(element)) {
                newarr.push(element);
            }
        });
        return newarr;
}

以上两个方法结合arr使用!

方法三:对象属性名不能重复

利用对象的属性不能相同的特点进行去重,也是可以考虑的一种方法。代码如下所示。

  let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let obj = {};
        for (let i = 0; i < ary.length; i++) {
            let cur = ary[i];
            if (obj[cur]需 {
                //ary.splice(i,1);// 导致数组塌陷
                ary[i] = ary[ary.length - 1];
                ary.length--;// 删除最后一项
                i--;
                continue;
            }
            obj[cur] = cur;// 给obj新增键值对;属性名和属性值是一样的
        }
    }
    unique(arr);

方法四:indexOf

indexof方法用于在数组中查找指定元素第一次出现的位置。

 let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let newAry = [];
        for (let i = 0; i < ary.length; i++) {
            let cur = ary[i];
            if (newAry.indexOf(cur) === -1) {
                newAry.push(cur);
            }
        }
        return newAry;
    }
    unique(arr)

方法五:includes :包含;如果数组包含那一项,返回true;不包含返回false;

   let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let newAry = [];
        let len = ary.length;
        for (let i = 0; i < len; i++) {
            let cur = ary[i];
            if (!newAry.includes(cur)) {
                newAry.push(cur);
            }
        }
        return newAry;
    }
    console.log(unique(arr));

方法六:hasOwnProperty : 检测属性名是否是对象的一个私有属性;返回一个布尔值;

这就是我在其中一次面试中对数组去重的一次总结,也算是我对数组去重的巩固。我们总共介绍了三种方式,分别是Set方法、forEach()结合includes()、利用对象的属性,这三种方法各有各的特点,都能达到去重的效果。

    let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let obj = {};
        return ary.filter(function (item, index, a) {
            // item : 数组每一个成员
            // index: 成员对应的索引
            // a : 整个数组
            // hasOwnProperty来校验的该属性是否出现过;
            return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item + item] = true;
            if (obj.hasOwnProperty(typeof item + item)) {
                return false
            } else {
                obj[typeof item + item] = true;
                return true;
            }
        })
    }
    console.log(unique(arr))

方法七:filter+indexOf

    let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        return ary.filter(function (item, index, a) {
            return ary.indexOf(item) === index;
        })
    }
    console.log(unique(arr));

方法八:splice

    let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        for (let i = 0; i < ary.length; i++) {
            for (j = i + 1; j < ary.length; j++) {
                if (ary[i] === ary[j]) {
                    ary.splice(j, 1);
                    j--;
                }
            }
        }
        return ary;
    }
    unique(arr);

方法九:递归

 let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let len = ary.length;
        ary = ary.sort(function (a, b) {
            return a - b;
        });
        function loop(index) {
            if (index >= 1) {
                if (ary[index] === ary[index - 1]) {
                    ary.splice(index, 1);
                }
                loop(index - 1)
            }
        }
        loop(len - 1);
        return ary;
    }
    console.log(unique(arr));

方法十:Map :利用了Map数据结构存值的特点;

 let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let newAry = [];
        let map = new Map();
        for (let i = 0; i < ary.length; i++) {
            if (!map.has(ary[i])) {
                map.set(ary[i], true);
                newAry.push(ary[i]);
            }
        }
    }
    unique(arr);

方法十一:reduce

    let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        // reduce : 第一个是函数,第二个参数会传给第一次回调的prev;
        return ary.reduce((prev, next) => {
            // 该函数返回值是下一次执行的prev;
            return prev.includes(next) ? prev : [...prev, next];
        }, [])
    }
    console.log(unique(arr));

方法十二:类似于方法一的set,用了剩余运算符...

    let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    let a = [...new Set(arr)];
    console.log(a);

方法十三:sort

利用sort排序方法,对a减b形式再利用for循环进行查找,查找到了向重的数字使用splice割掉

let arr = [12, 1, 12, 3, 1, 88, 66, 9, 66];
    function unique(ary) {
        let a = ary.sort(function (a, b) {
            return a - b;
        });
        for (let i = 0; i < a.length; i++) {
            if (a[i] === a[i + 1]) {
                a.splice(i + 1, 1);
                i--;
            }
        }
        return a;
    }
    unique(arr)

今天先整理出这些去重方法,欢迎大佬们指点补充~ღ( ´・ᴗ・` )比心