资讯专栏INFORMATION COLUMN

浅谈Javascript数组去重

Taste / 337人阅读

摘要:总结,其实数组去重无非就是判断一个元素在数组中是否有重复的值。参考自从数组去重谈性能优化也谈数组去重数组去重谢谢飞的更高指出的问题同步于个人博客

javascript 数组 array 去重 distinct unique

刚好前天面试的时候面试官问到了数组去重的问题,当时有点语塞只想到用了两个循环检测(其实模模糊糊想到了hash的方法做但是由于记得不清不敢说= =!),思路是检测是否有元素重复,然后将只出现一次的元素推入到新数组中,然后返回新数组。然后面试官又问这种方法的时间效率,于是黑线了。so这两天看了一下相关的文章,在这里也总结一下javascript数组去重的方法。

两层循环检测重复元素法

首先,介绍一下大家都会想到的两层循环的demo,如下例:

function distinct(arr) {
    var ret = [],
        length = arr.length;
    for(var i = 0;i < length; i++){
        for(j = i+1; j


如上的代码实现是轻松易得的,思路如下:

首先外层循环比遍历整个数组

内层循环匹配是否有值重复

a.如判断有相同元素则自增i变量,跳出i的循环
b.如判断无时则将无相等值的元素推入到ret数组中

3.返回ret。

优点:便捷易懂,大多数程序员能想到。
缺点:很明显时间消耗太高,两层循环时间消耗太多,时间的消耗为O(n^2^),在进行大量数据处理时会消耗大量资源。而且该方法无法处理字符和数组,如下例:

var arr = [1,23,4,5,6,7,"1",22,3,1,2];
distinct(arr);                  //返回[23, 4, 5, 6, 7, "1", 22, 3, 1, 2]

所以我们可以开始考虑一些别的方法优化数组去重:

sort重排数组去除重复元素索引法(!每一个浏览器中的sort函数的排序方法并不一样,所以实现结果可能会有差异,经测试在chrome下测试别的数组实现会出现问题)

这种方法就是先讲原数组使用sort方法将数组重排,以得到将相同元素为相邻位的一个新数组。该方法如下:

function distinct(arr){
    var self = arr;
        list = self.concat().sort();
        
    list.sort(function(a, b){
        if(a === b){
            var ind = self.indexOf(a);
            self.splice(ind, 1);
        }
    });
    return self;
}
var arra = [1,2,3,3,1,1,1,"1"];
var arr = distinct(arra);                //返回的数组为[2,3,1,"1"]

同样的,在使用这种方法的重排的时候,仍然会有一定的资源消耗,在sort()函数中回调函数是使用的冒泡排序,而冒泡排序的效率并不高。但是使用这种方法的效率仍然比上一种方法的效率高,因为在此例中只出现了一次循环遍历。

优点:程序简洁,效率较高。
缺点:1.仍然无法解决数字1和字符"1"的去除。2.依赖indexOf方法,我们知道在IE6~8中并未支持indexOf()方法。
所以我们还要做一些兼容性的处理。如下:

var indexOf = [].indexOf ?
    function indexOf(arr, item){
        return arr.indexOf(item);
    }:
    function indexOf(arr, item){
        for(var i = 0; i < arr.length; i++){
            if(arr[i] === item){
                retrun i;            
            }
        }
        return -1;
    }
    
function distinct(arr){
    var self = arr;
        list = self.concat().sort();
        
    list.sort(function(a, b){
        if(a === b){
            var ind = self.indexOf(arr, a);
            self.splice(ind, 1);
        }
    });
    return self;
}    
将数组元素值存为对象的属性
function distinct(arr) {
    var ret = [],
        json = {},
        length = arr.length;
        
    for(var i = 0; i < length; i++){
        var val = arr[i];
        if(!json[val]){
            json[val] = 1;
            ret.push(val);
        }
    }
    return ret;
}

var arra = [1,2,3,5,7,1,2,"1"];

以上方法更加的简洁,而且也能在原来的基础上区分字符‘1’和数字1的区别。
在此例中思路如下:
1.循环遍历每一个元素
2.检测在json对象中是否含遍历到的元素的值

a: 如果是则跳过
b: 如果否存入json对象中该属性名的值设为1

3.将存入对象了元素的值推入到新数组中,返回新数组。

总结,其实数组去重无非就是判断一个元素在数组中是否有重复的值。优化也是一直改变判定元素是否重复的一些技巧,如例1中是遍历数组,例2是重排数组获得索引,例3则别出心裁将元素的值作为对象的属性。

参考自:
从 JavaScript 数组去重谈性能优化
也谈javascript数组去重
js数组去重
谢谢@飞的更高 指出的问题

同步于个人博客:http://penouc.com

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78122.html

相关文章

  • 浅谈JS中 reduce() 的用法

    摘要:一语法其中,表示将要原数组表示上一次调用回调时的返回值,或者初始值表示当前正在处理的数组元素表示当前正在处理的数组元素的索引,若提供值,则索引为,否则索引为表示初始值。 一、语法 arr.reduce(function(prev,cur,index,arr){...}, init); 其中,arr 表示将要原数组;prev 表示上一次调用回调时的返回值,或者初始值 init;cur 表...

    gplane 评论0 收藏0
  • 再见,重复的你(数组去重

    摘要:前言昨天跟在前端好友聊天时,她提到了一个问题数组去重你会怎么写。利用将结构转换成数组拓展运算符内部使用循环参考浅谈数组去重数组去重小结标准入门第版 前言 昨天跟在前端好友聊天时,她提到了一个问题:数组去重你会怎么写?。想了想,其实有好几种方法,决定在这篇笔记中做一些记录。 思路一: 双层循环,外层循环元素,内层循环时比较值 如果有相同的值则跳过,不相同则push进数组 Array....

    EsgynChina 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • JavasScript重难点知识

    摘要:忍者级别的函数操作对于什么是匿名函数,这里就不做过多介绍了。我们需要知道的是,对于而言,匿名函数是一个很重要且具有逻辑性的特性。通常,匿名函数的使用情况是创建一个供以后使用的函数。 JS 中的递归 递归, 递归基础, 斐波那契数列, 使用递归方式深拷贝, 自定义事件添加 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果...

    forsigner 评论0 收藏0
  • ES6常用语法到Node浅谈

    摘要:是解释性语言因服务端的应用,而贯通了前后台。关于和声明的变量和声明的变量整体,会被提升到当前作用域的顶部。做后台服务端,处理请求的代码,得自己实现了。为提高下载速度,可通过来切换镜像源。 JS是解释性语言,因node服务端的应用,而贯通了前后台。 【ES6】 关于var和let var: 1.var声明的变量和function声明的变量整体,会被提升到当前作用域的顶部。 2...

    weizx 评论0 收藏0

发表评论

0条评论

Taste

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<