js学习笔记:数组去重

数组去重是面试中常见的一个算法问题。

数组去重,一般需求是给你一个数组,调用去重方法,返回数值副本,副本中没有重复元素。一般来说,两个元素通过 === 比较返回 true 的视为相同元素,需要去重,所以,1 和 “1” 是不同的元素,1 和 new Number(1) 是不同的元素,{}和 {} 是不同的元素(引用不同)。

方法一

利用另一个数组res,遍历原数组,如果res中没有的话就加入,如果已经存在的话就略过。最后返回res数组。
这是一种容易想到的O(n*n)的解法。

function unique(nums){
    var res = [];
    for(var i=0;i<nums.length;i++){
        for(var j = 0;j<res.length;j++){
            if(res[j] === nums[i]){
                break;
            }
        }
        if(j == res.length){
            res.push(nums[i]);
        }
    }
    return res; 
}

代码非常简单,那么是否能更简洁些?如果不考虑浏览器兼容,我们可以用 ES5 提供的 Array.prototype.indexOf 方法来简化代码:

function unique(nums){
    var res = [];
    for(var i=0;i<nums.length;i++){
        (res.indexOf(nums[i]) == -1) && res.push(nums[i]);
    }
    return res; 
}

方法二

filter()是数组的一个迭代方法,每一个迭代方法都对数组中的每一项运行给定函数,此方法接受一个函数参数,此函数接收三个参数:

  • 数组项的值 item
  • 该项在数组中的位置 index
  • 数组对象本身 array

filter()则返回该函数会返回true的项所组成的数组。

function unique(nums){
    var res = nums.filter(function(item,index,array){
        return array.indexOf(item) == index;
    });
    return res; 
}

filter()中这个函数的含义是利用indexOf()检查每个项的位置是否等于index,由于indexOf()只会返回第一次出现的项的位置,因此如果有重复的数出现的话,这个函数返回false,此重复的数便不会被加入到返回的数组中。

方法三

将数组用 sort 排序后,理论上相同的元素会被放在相邻的位置,那么比较前后位置的元素就可以了。

function unique(nums){
    nums.sort();
    var res = [nums[0]];
    for(var i=1;i<nums.length;i++){
        if(nums[i] !== nums[i-1]){
            res.push(nums[i]);
        }
    }
    return res;
}

这种方法也可能出错,因为“1”和1会被排在一起,所以如果数组中存在1,’1’,1这样的情况,则会排错。

方法四

利用Object作为一个哈希表。

function unique(nums){
    var hash = {};
    var res = nums.filter(function(item){
        return hash[item]?false:(hash[item] = true);
    }); 
    return res;
}

因为 Object 的 key 值都是 String 类型,所以对于 1 和 “1” 无法分别,我们可以稍微改进下,将类型也存入 key 中:

function unique(nums){
    var hash = {};
    var res = [];
    for(var i=0;i<nums.length;i++){
        var key = typeof nums[i] + nums[i];
        if(!hash[key]){
            hash[key] = true;
            res.push(nums[i]);
        }
    }
    return res;
}

方法五

利用ES6的Set结构,由于Set存储的都是不重复的值,因此可以将数组传给Set生成一个没有重复数的set对象,再转换回数组。

可以使用Array.from:

Array.from(new Set(arr));

也可以使用扩展操作符

[...new Set(arr)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值