zoukankan      html  css  js  c++  java
  • JS数组去重

    案例分析:

    随机生成20个十以内的数字。

    随机生成10以内数字

    let arr = Array.from({length:20},=>Math.random()*10|0);
    console.log(arr);
    //输出结果:
    [5,4,7,0,0,0,8,0,2,9,3,0,0,1,5,9,2,8,6,0]

    思路:

    双层循环,外层循环元素,内层循环时比较值

    值相同时,则删去这个值

    利用splice直接在原数组进行操作

    Array.prototype.distinct = function (){
        var arr = this,
            i,
            j,
            len = arr.length;
     
        for(i = 0; i < len; i++){
            for(j = i + 1; j < len; j++){
                if(arr[i] == arr[j]){
                    arr.splice(j,1);
                    len--;
                    j--;
                }
            }
        }
        return arr;
    };
     
    var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];
    var b = a.distinct();
    console.log(b.toString()); //1,2,3,4,5,6,56

    注意:删除相同值时,数组长度相应减一。

    但是,我们要注意的是,此种方法会改变原数组的值,也就是说,我们改变了arr的结果。如果不想改变原数组改怎么办呢?

     

    不改变原数组

    Array.prototype.distinct = function(){
        var arr = this,
            result = [],
            i,
            j,
            len = arr.length;
      
        for(i = 0; i < len; i++){
            for(j = i + 1; j < len; j++){
                if(arr[i] === arr[j]){
                    j = ++i;
                }
            }
            result.push(arr[i]);
        }
        return result;
    }
    var arra = [1,2,3,4,4,1,1,2,1,1,1];
    arra.distinct()

    此种方法,先创建一个空数组,然后利用双层循环,符合的,push进result数组中,若遇到相同值,则直接跳过,不再进行push操作。这样,我们就避免了对原数组的操作。

    这种方法解决了操作原数组的问题,但是,如果数组的值特别大怎么办?比如说,数组arr有10000个值,找到第一项后,比较数组后面的值,那我们需要比较9999次,找到第二项,需要比较9998次。但是,我们已经确定了,我们的结果集中,就10个数,这样显然不是我们想要的,怎么办呢?

    为了提升性能,我们可以从结果集中进行比较。

     

    indexOf的使用

    let rs = [];
    for(let i=0;i<arr.length;i++){
        if(rs.indexOf arr[i] === -1){
            rs.push(arr[i])
        }
    };
    console.log(rs)

    通过indexOf方法,如果得到的值为-1,则确定数组中不存在该值,这样,我们就把arr[i],push到数组中。这样我们就得到了去重后的数组。

    既然我们想到了indexOf方法,那我们是不是还能有更加简便的方法来使数组去重呢?

    仔细想想,我们就会想到,数组的filter方法。

     

    数组的filter方法

    console.log(arr.filter(function(element,index,self){
        return self.indexOf(element) === index;
     }));

    element是数组的每个值,index是数组的索引,self是数组本身。

    当使用indexOf方法时,如果数组的每项的indexOf方法得到的值与数组索引相同,则证明此值第一次出现,如果数组的索引与index的值不相同,则证明不是第一次出现。

    前面我们介绍的这些方法,都是使用数组本身的方法。其实在js中,还有一个特殊的东西,叫做对象。

     

    对象去重法

    var o={};
    var new_arr=[];
    for(var i=0;i<arr.length;i++){
        var k=arr[i];
        if(!o[k]){
            o[k]=true;
            new_arr.push(k);
        }
    }
    console.log(new_arr)

    这种方法利用到,对象的属性唯一行,来进行判断。

    为什么要用到这种方法呢?其实前面的方法,都用到了双层循环,indexOf也不例外,但是利用对象的key来做判断时,我们只用到了一次循环,这样就会大大增加运行的性能,利用对象去重也是这些方法中运行速度最快的一种。

    前面介绍到的这些种方法,都是ES3,ES5中用到的方法,接下来我们介绍一下利用ES6来进行数组去重的方法。

    在本文的开头,我们创建随机数组的时候,用到了 Array.from()方法,在ES6中新增了from方法。接下来我们借助from方法和一些其他的方法来把数组进行去重。

     

    form方法

     

    let rs = Array.from(arr);
    //得到与当前一样的数组

    let rs= Array.from(new Set(arr)); // 利用ES6的Set方法进行去重。
    console.log([...new Set(arr)]); //这种方法只用到了13个字符,也是数组去重最方便的方法。

    总结:

    数组去重在我们日常的开发中用到的比较少,但是我们要理解其中的逻辑,以便于我们更好的进行其他的开发任务。

  • 相关阅读:
    Quartz.NET总结(八)如何根据自己需要配置Topshelf 服务
    Golang 入门系列(十七)几个常见的并发模型——生产者消费者模型
    能避开很多坑的mysql面试题,你知道吗?
    Golang 入门系列(十六)锁的使用场景主要涉及到哪些?读写锁为什么会比普通锁快
    Thrift总结(四)Thrift实现双向通信
    Golang 入门系列(十五)如何理解go的并发?
    Nginx总结(六)nginx实现负载均衡
    Nginx总结(五)如何配置nginx和tomcat实现反向代理
    Nginx总结(四)基于域名的虚拟主机配置
    Nginx总结(三)基于端口的虚拟主机配置
  • 原文地址:https://www.cnblogs.com/kingchan/p/10959265.html
Copyright © 2011-2022 走看看