Js数组去重的五种方式

一、利用双层 for 循环

Talk is cheap,Show you the code.

var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
distinct(fruits);
console.log(fruits);
//(4) ["苹果", "香蕉", "葡萄", "火龙果"]
//双重循环
function distinct(arr) {
    for (let i=0, len=arr.length; i<len; i++) {
        for (let j=i+1; j<len; j++) {
            if (arr[i] == arr[j]) {
                arr.splice(j, 1);
                // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
                len--;
                j--;
            }
        }
    }
    return arr;
}

这种方式的去重简单来说就是我从第一个开始循环剩下的与之对比,去掉相同的所以这个的方式它的时间复杂度是O(n^2),如果数组长度很大,效率会很低,另外如果数组中有NAN的话也是无法去重的。(NaN==NaN为false)

如果数组里面是对象,我们知道每个对象都会开辟一个新的空间,所以在判断相等时内容一样,也不会一样,所以在构造数据时,我们可以在里面放一个唯一标识,一般后端给我妈传回来的数据应该都有一个id。

    var student=[
        {
            id:1,
            name:'zs'
        },
        {
            id:2,
            name:'ls'
        },
        {
            id:3,
            name:'we'
        },
        {
            id:3,
            name:'we'
        },
        {
            id:1,
            name:'zs'
        },
    ]
distinct(student);
console.log(student);
// 0: {id: 1, name: "zs"}
// 1: {id: 2, name: "ls"}
// 2: {id: 3, name: "we"}
// length: 3
function distinct(arr) {
    for (let i=0, len=arr.length; i<len; i++) {
        for (let j=i+1; j<len; j++) {
            if (arr[i].id == arr[j].id) {
                arr.splice(j, 1);
                // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
                len--;
                j--;
            }
        }
    }
    return arr;
}

二、利用数组方法

var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
var fruits1Two=['苹果','牛油果','桃子','菠萝','桃子']
console.log(distinct(fruits,fruits1Two));
//(7) ["苹果", "香蕉", "葡萄", "火龙果", "牛油果", "桃子", "菠萝"]
//Array.filter() 加 indexOf
function distinct3(a, b) {
    let arr = a.concat(b);
    return arr.filter((item, index)=> {
        return arr.indexOf(item) === index
    })
}

利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素。此方法对象不去重,NaN会被忽落掉(arr.indexOf(Nan)=-1)。

三、利用排序

var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
console.log(distinct(fruits));
// ["火龙果", "苹果", "葡萄", "香蕉"]
function distinct(array) {
    var res = [];
    var sortedArray = array.concat().sort();
    var seen;
    for (var i = 0, len = sortedArray.length; i < len; i++) {
        // 如果是第一个元素或者相邻的元素不相同
        if (!i || seen !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen = sortedArray[i];
    }
    return res;
}

先调用数组的排序方法,然后比较相邻的两个是否相等从而实现去重。此方法对象和NaN不去重,数字1与字符串1也不去重。
注:V8引擎 的 sort() 方法在数组长度小于等于10的情况下,会使用插入排序,大于10的情况下会使用快速排序

四、利用ES6中的Set方法

var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
console.log(distinct(fruits));
// ["苹果", "香蕉", "葡萄", "火龙果"]
function distinct(array) {
   return Array.from(new Set(array));
}

可以简化为:

function distinct(array) {
    return [...new Set(array)];
}

甚至:

let distinct = (a) => [...new Set(a)]

Es6提供的Set 结构的一个特性就是成员值都是唯一的,没有重复的值,此方法对象不去重,NaN去重。

五、利用Object 键值对

function distinct(array) {
    var obj = {};
    return array.filter(function(item, index, array){
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

这种方法是利用一个空的 Object 对象,我们把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的,但是最后请注意这里obj[typeof item + item] = true没有直接使用obj[item],是因为 123 和 ‘123’ 是不同的,直接使用前面的方法会判断为同一个值,因为对象的键值只能是字符串,所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题。此方法对象、NaN均去重。

参考:https://mp.weixin.qq.com/s/T_HZEqlUqqtufBPtg3eWvA

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值