首頁 > web前端 > js教程 > javascript實作陣列去重的多種方法_javascript技巧

javascript實作陣列去重的多種方法_javascript技巧

WBOY
發布: 2016-05-16 15:10:54
原創
1427 人瀏覽過

廢話不多說,直接拿乾貨!

先說說這個實例的要求:寫一個方法實作陣列的去重。 (要求:執行方法,傳遞一個數組,返回去重後的新數組,原始數組不變,實現過程中只能用一層循環,雙層嵌套循環也可寫,只做參考);

先跟初學者解釋一下什麼叫數組去重(老鳥跳過):意思就是講數組裡面重複的元素去掉,比如說var arr = [3,2,4,2,1,2];數組去重得到的新數組是[3,2,4,1],就是這麼一個函數。

實現方法比較簡單,實現的方式也比較多,很多大牛也寫過相關的文章,之所以寫這邊博客,旨在一是備忘,二是給初學者能更好的理解其實現的原理,好,我們看第一種實現方式:

第一種,透過遍歷新數組來去重

var arr = [1,'b','b',4,3,3,4,5,1];
     
    //第一种
    Array.prototype.unique1 = function(){
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        if(arr1.indexOf(this[i]) == -1){//判断目标数组中在原数组里是否存在
          arr1.push(this[i]);
        } 
      } 
      return arr1;
    }
    console.log(arr); //[1,'b','b',4,3,3,4,5,1]
    console.log(arr.unique1()); //[1, "b", 4, 3, 5]
    //这种方法的主要思路就是,新建一个数组,然后在原数组中,从第一个开始,看看新数组里面有没有这个元素,如果有,就忽略,然后进行下一个,如果没有,则把这个元素存到新数组里面,
    //也就是说,每一次比较,都会遍历新数组,直到找到相同元素为止,比较耗性能
登入後複製

如果大家不習慣這個寫法,可以改成下面的寫法,效果是一樣的:

var arr = [1,'b','b',4,3,3,4,5,1];

function unique1(arr){
      var arr1 = [];
      for(var i=0;i<arr.length;i++){
        if(arr1.indexOf(arr[i]) == -1){//判断目标数组中在原数组里是否存在
          arr1.push(arr[i]); 
        } 
      } 
      return arr1;
    }
    console.log(arr); //[1,'b','b',4,3,3,4,5,1]
    console.log(unique1(arr)); //[1, "b", 4, 3, 5]

登入後複製

下面的方法我就不改寫法了,你們可以按照上面的格式來改寫一下,結果我也不輸出了,因為結果是一樣的,註釋寫在代碼中,慢慢體會一下

第二種,透過hash表(這個概念有點大,具體原理就不在這裡細說了,有時間我會單獨寫一遍,這是好東西)實現

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique2 = function(){
      var hash = {}; //定义一个hash表
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        /*
          这里比较难理解,我们一步一步来看:
          hash是一个对象,则存在键值对(key:value),只不过现在是为空的,所以hash[key] = value;
          第一步:i=0;this[i]=this[0]=1; hash[this[0]] = hash[1] , 因为hash初始为空,没有找到key=1的值,所以然后undefined,
          执行下一步:hash[1] = true(此时hash对象就有了第一组键值对),将原数组的第一个数添加到新数组中,重复第一步
          因为不重复的判断hash的值都是undefined,而重复的都为true了,所以不重复都被添加到新数组中
          因为hash表存的值是存的地址,放在堆内存中,所以有多少个不重复的元素,就要分多少个内存来存放,所以这种方法比较占内存,但是相比之下,这种的运算运动是最快的,
          这也就是用空间来换取时间了,数据量比较小,推荐用此方法
        */
        if(! hash[this[i]]){
          hash[this[i]] = true;
          arr1.push(this[i]);
        }
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique2());
登入後複製


第三種,透過遍歷自身的位置是否一致來實現

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique3 = function(){
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        if(this.indexOf(this[i])==i){
        //这里也是indexOf遍历,看从第一个元素在原数组中的位置,如果第一次出现的位置和下标相等,说明当前元素的不重复的,如果不等,说明该元素前面已经出现过
          arr1.push(this[i]);
        }
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique3());
登入後複製


第四種,這個有點意思,只能​​運用到特殊場合,就是先跟數組排序,然後22比較,輸出一個排序過的新數組

Array.prototype.unique4 = function(){
      /*
        这里是思路是,先排序(默认从小到大),然后将原数组的第一个给新数组,
        因为是经过排序的,所以重复的只会存在在相邻位置
        这里就相当于是做22比较,如果相等,则进行下一组,如果不相等,则把这个数存到新数组中,用这个数再进行比较
      */
      this.sort();
      var arr1 = [this[0]];
      for(var i=1;i<this.length;i++){
        if(this[i] !== arr1[arr1.length-1]){
          arr1.push(this[i]);
        } 
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique4());
登入後複製

哇哈,打完收工!

要求裡面還說,可以使用雙層巢狀循環來實現,無法就是用2層for循環,讓每一個與原數組去比較

Array.prototype.unique5 = function(){
      //双层循环,一一比较
      for(var i=0;i<this.length;i++){ //从0开始
        for(j= i+1;j<this.length;j++){ //从1开始,逐个比较
          if(this[i] === this[j]){ //如果恒定
            this.splice(j,1);  //就将这个元素删掉
          } 
        } 
      }
      return this;  
    }
    console.log(arr);
    console.log(arr.unique5());
登入後複製

這種寫法的循環次數太多,不推薦,有人會說,第一種和第三種不也是每次都遍歷一遍嗎?跟第5種感覺也差不多呢?是的,你能這麼理解,表示你理解了,但是呢,又不是特別的理解,我們說差不多那可就差太多了,indexOf()表示的是找到第一個匹配的元素就會

停止遍歷,而第5種則是不管找不找得到,都會把整個數組遍歷一遍,如果資料量大,那你覺得哪個效能要好一點?

特別注意的一點:如果在比較兩兩之間的值是全等或不等的時候,一定要用恆定(===)和不恆定(!==),因為這會涉及到元素的類型上,如1與'1'是不恆等的!

上面的可真是乾貨了,一點水分都沒有,只能靠大家自己領悟了!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板