JS-数组去重方法

93 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

一、双for循环方式

let arr = [1,2,3,4,5,4,2,7,3,7,1];

//1、双for循环方式
for(let i = 0;i<arr.length;i++){
    for(let j = i+1;j<arr.length;j++){
        if(arr[i] === arr[j]){
            //将随后一项放到j的位置,然后把最后一项删除
            //这样不会导致索引前置,可提高性能
            arr[j] = arr[arr.length-1];
            arr.pop();
            // arr.length--
            j--;
        }
    }
}
console.log(arr);

(一)splice引起的数组塌陷问题

在删除重复项后,后面每一项的索引都会向前提一位,这样(如果删除的这一项后面还有1000万项,那么这1000万项的索引都要向前提一位),这样会大大的消耗性能。
解决:我们用最后一项替换删除项,再删除最后一项(下一轮循环还要从当前项开始),这样就不会导致索引前置,从而达到优化性能的目的。

二、对象键值对的方式

let obj = {};
for(let i = 0;i<arr.length;i++){
    if(obj[arr[i]]!==undefined){
        arr[i] = arr[arr.length-1];
        arr.pop();
        i--
    }else{
        obj[arr[i]] = arr[i];
    }
}
console.log(arr);

(一)优点:

只有一个循环,所以性能很好

(二)缺点:

1.如果数组中出现对象则会存在问题,因为对象的属性名不能是对象,遇到会转换为字符串;
2.如果数组中存在数字10和字符串'10',则也会认为是重复的,因为对象中的属性名是数字和字符串没有区别的;
3.数组中的值如果是undefined可能也会出现问题....

三、indexOf

let newArr = [];
arr.forEach((item,index,arrt)=>{
    if(newArr.indexOf(item) === -1){
        newArr.push(item);
    }
})
console.log(newArr);

(一)缺点

indexOf低版本浏览器不兼容

四、ES6新特性:Set方式

Set数据结构会自动去重
let newArr = Array.from(new Set(arr));
let newArr = [...new Set(arr)];
console.log(newArr);

(一)缺点

低版本浏览器不兼容