[javascript] 數組去重問題

來源:互聯網
上載者:User
數組去重問題

src: http://yiminghe.javaeye.com/blog/524716

很經典的問題,去除數組中的重複元素,上網搜了一下,發現大多數無論轉載還是原創都是這個解法:


錯誤解法:

Js代碼  
  1. function uniq(array) {   
  2.     var map={};    
  3.     var re=[];    
  4.     for(var i=0,l=array.length;i<l;i++) {    
  5.         if(typeof map[array[i]] == "undefined"){    
  6.             map[array[i]]=1;   
  7.             re.push(array[i]);   
  8.         }   
  9.     }   
  10.     return re;    
  11. }  
function uniq(array) {var map={};var re=[];for(var i=0,l=array.length;i<l;i++) {if(typeof map[array[i]] == "undefined"){map[array[i]]=1;re.push(array[i]);}}return re;}

如果用過java等進階語言的話,初看這段代碼確實沒有什麼問題:下面的例子:

Js代碼  
  1. uniq([1,2,1,2,4]);  
uniq([1,2,1,2,4]);

也能正常運行。



可再試試下面的例子:

Js代碼  
  1. uniq([{x:1},"[object Object]"]);   
  2. uniq([{x:1},{z:2}]);  
uniq([{x:1},"[object Object]"]);uniq([{x:1},{z:2}]);

 

運行一下就會知道錯在哪裡了!

HashMap In Java :

在 java 中如 HashMap 類可以使用對象做為 key (內部實現使用 hashcode散列到桶 以及桶內equals[預設記憶體位址]比較),如:

Java代碼  
  1. class Holder {   
  2.     int i;   
  3. }   
  4.  public class Test3 {   
  5.   
  6.     /**  
  7.      * @param args  
  8.      */  
  9.     public static void main(String[] args) {   
  10.         HashMap<Holder, Holder> map=new HashMap<Holder, Holder>();   
  11.         Holder key= new Holder();   
  12.         Holder value= new Holder();   
  13.         value.i=1;   
  14.         map.put(key, value);   
  15.         Holder key2=new Holder();    
  16.         System.out.println(map.get(key).i);   
  17.         System.out.println(map.get(key2));   
  18.     }   
  19.   
  20. }  
class Holder {int i;}public class Test3 {/** * @param args */public static void main(String[] args) {HashMap<Holder, Holder> map=new HashMap<Holder, Holder>();Holder key= new Holder();Holder value= new Holder();value.i=1;map.put(key, value);Holder key2=new Holder(); System.out.println(map.get(key).i);System.out.println(map.get(key2));}}

Object In Javascript:

而在 javascript 中畢竟沒有map,只有對象這個概念,而對象則要求其屬性值必須為字串,如果提供給對象的屬性不是字串,那麼則會自動調用 toString 方法轉化為字串形式,例如:

Js代碼  
  1. var x={};   
  2.  var y={   
  3.     toString:function(){   
  4.         return "z";   
  5.      }   
  6. };   
  7.   
  8. x[y]=1;   
  9. alert(x["z"]);  
var x={};var y={    toString:function(){        return "z";     }};x[y]=1;alert(x["z"]);

那麼由上述例子就可以知道第一個程式為什麼是錯誤的了 。

正確答案:

我們無法利用進階語言提供的map類庫,那就只好兩遍遍曆數組了,也是 taobao ued提供的標準答案:


注意 === 使用。

Js代碼  
  1. /**  
  2. *unique the array  
  3. *@param {Array} array array to unique  
  4. *@return {Array} uniqued array ,note change parameter  
  5. */  
  6.  function undulpicate(array){   
  7.     for(var i=0;i<array.length;i++) {   
  8.         for(var j=i+1;j<array.length;j++) {   
  9.             //注意 ===   
  10.             if(array[i]===array[j]) {   
  11.                 array.splice(j,1);   
  12.                 j--;   
  13.             }   
  14.         }   
  15.     }   
  16.     return array;   
  17. }  
/***unique the array*@param {Array} array array to unique*@return {Array} uniqued array ,note change parameter*/function undulpicate(array){for(var i=0;i<array.length;i++) {for(var j=i+1;j<array.length;j++) {//注意 ===if(array[i]===array[j]) {array.splice(j,1);j--;}}}return array;}

 

ps: Jquery Uniq Node


如果我們確認數組裡每個元素都是對象,那麼可以用加標籤的方式,給對象元素添加標籤,從而把時間複雜度提升到 O(n) :

Js代碼  
  1. var x={z:1};   
  2.  var y={q:2};   
  3.  function uniqObjects(array){   
  4.     var re=[];   
  5.     for(var i=0,l=array.length;i<l;i++) {   
  6.         if(typeof array[i]["_uniqObjects"] == "undefined"){   
  7.             //添加標籤   
  8.                         array[i]["_uniqObjects"]=1;   
  9.             re.push(array[i]);   
  10.         }   
  11.     }   
  12.         //取出標籤   
  13.     for(var i=0,l=re.length;i<l;i++) {   
  14.         delete re[i]["_uniqObjects"];   
  15.     }   
  16.     return re;   
  17. }   
  18. uniqObjects([x,y,x]);  
var x={z:1};var y={q:2};function uniqObjects(array){var re=[];for(var i=0,l=array.length;i<l;i++) {if(typeof array[i]["_uniqObjects"] == "undefined"){//添加標籤                        array[i]["_uniqObjects"]=1;re.push(array[i]);}}        //取出標籤for(var i=0,l=re.length;i<l;i++) {delete re[i]["_uniqObjects"];}return re;}uniqObjects([x,y,x]);

這也正是 jquery 的思路,由於每個元素都是節點數組,當然可以這樣做了:

Js代碼  
  1. unique: function( array ) {   
  2.         var ret = [], done = {};   
  3.   
  4.         try {   
  5.   
  6.             for ( var i = 0, length = array.length; i < length; i++ ) {   
  7.                 var id = jQuery.data( array[ i ] );   
  8.   
  9.                 if ( !done[ id ] ) {   
  10.                     done[ id ] = true;   
  11.                     ret.push( array[ i ] );   
  12.                 }   
  13.             }   
  14.   
  15.         } catch( e ) {   
  16.             ret = array;   
  17.         }   
  18.   
  19.         return ret;   
  20.     },  
unique: function( array ) {var ret = [], done = {};try {for ( var i = 0, length = array.length; i < length; i++ ) {var id = jQuery.data( array[ i ] );if ( !done[ id ] ) {done[ id ] = true;ret.push( array[ i ] );}}} catch( e ) {ret = array;}return ret;},

 

 

注意:對基本類型,如 number,string,不要使用這種方式,它們會產生臨時對象,並不能達到預期效果!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.