數組去重-

 

數組去重:將數組中重複的元素找出來並刪減爲一個。目的很簡單,方法倒有不少,以致於我費盡心思去考慮各類方法的好處壞處並進行對比,最終得出在各類場合適用的不一樣方法。但願有不一樣意見的儘管指出來。

【方法1】:

 

/*
* function unique1(array)
* 原理:新定義一個數組,結合一個對象輔助
* 時間複雜度:O(n)
* 適用範圍:全數字、全字符串
* 方法缺點:混淆數字與數字字符串,對於對象無效
*/ 
function unique1(array) {
if (!array) return array;
var obj = {}, a = [];
for (var i = 0, iLen = array.length; i < iLen; i++) {
if (!obj[array[i]]) {
a.push(array[i]);
obj[array[i]] = true;
}
}
return a;
}
 

簡單易懂的方法,可是對於只含數字的字符串(如 '12')沒法和數字區分開來,對於對象也沒法區分,能夠在底部的測試例子中看到。數組

【方法2】:函數

 

 

 

/*
* function unique2(arr)
* 原理:新定義一個數組,結合一個對象輔助
* 時間複雜度:O(n)
* 適用範圍:全數字、全字符串、數字與字符串混合
* 方法缺點:對於對象,全部對象最後只剩一個(無論鍵值對是否相同)
*/
function unique2(array) {
        if (!array) return array;
        var obj = {}, a = [];
        for (var i = 0, iLen = array.length; i < iLen; i++) {
            if ((typeof obj[array[i]]) != (typeof array[i]) || obj[array[i]] != array[i]) {
                a.push(array[i]);
                obj[array[i]] = array[i];
            }
        }o=obj;
        return a;
    }

 

這種方法在方法1的基礎上,可以分辨出數字字符串和數字,但對於對象仍無能爲力。測試

【方法3】:spa

 

 

 

 

/*
* function uniqExceptObj(array)
* 原理:查找相同值,對數組進行splice修改
* 時間複雜度:O(n2)
* 適用範圍:全數字、全字符串、數字與字符串混合、含有對象(不一樣對象的鍵值對均不一樣)
* 方法缺點:沒法區分具備相同鍵值對的不一樣對象
* 注意!array.length不要事先獲取,如 iLen=array.length; 由於循環過程當中array.length會變化
*/
對象

function uniqExceptObj(array){
var temp = array.slice(0); //設置一個輔助數組,避免直接修改原array數組
for(var i = 0; i < temp.length; i++){
for(var j = i + 1; j < temp.length; j++){
if(temp[i] === temp[j]){
temp.splice( j, 1 );
j--;
}
}
}
return temp;
}

 

如今,對於對象也能夠區分了。可是仍然沒法區分具備相同鍵值對的不一樣對象,那麼這也不是真正意義上的去重。而且,時間複雜度已經達到了O(n2)了。blog

【方法4】:字符串

 

/*
* function uniqueAll(array)
* 原理:用equal函數查找相同值,對數組進行splice修改
* 時間複雜度:O(n3)
* 適用範圍:所有
* 方法缺點:複雜度太大,時間消耗太大
* 說明:內置輔助函數 isEqual
* 注意!array.length不要事先獲取,如 iLen=array.length;
*/
it

function uniqueAll(array){
/* function isEqual(obj1,obj2)
* 功能:比較任何類型的兩個元素
* 結果:只有兩個元素類型相同且值相同時才返回真
*/
function isEqual(obj1,obj2){
if (obj1 === obj2) { return true; }
if (!(obj2 instanceof Object) || (obj2 === null)) { return false; } // null is not instanceof Object.
var p = 0; // count propoty of obj1
for (var k in obj1){
p++;
var o1 = obj1[k];
var o2 = obj2[k];
if ((o1 != null) && !(isEqual(o1,o2))){ return false; } // compare inner object.
}
for (var k in obj2){ // compare object property counter.
p--;
}
return p == 0;
}
var temp = array.slice(0); //設置一個輔助數組,避免直接修改原array數組
for(var i = 0; i < temp.length; i++){
for(var j = i + 1; j < temp.length; j++){
if( isEqual( temp[i],temp[j] )){
temp.splice(j,1);
j--;
}
}
}
return temp;
}

還是用方法3的思路,把各個數組元素進行對比,只是在對比時用了一個內置函數isEqual,用來有效地比較各類類型,包括對象。這種方法能夠有效地對任何類型數據進行處理,但缺點明顯,時間複雜度O(n3)。因此,在不須要對對象處理的時候,仍是避免使用的好。io

 

 

【終於到結論了】:
從以上的各類對比來看,咱們能夠得出一個前人早已得出的結論:「人無完人,金無足赤」。各個方法有各自不一樣的優勢和缺點。
當只須要處理字符串或只須要處理數字時,咱們能夠採用方法1;
當須要處理字符串和數字混合的數組而無需處理對象時,咱們採用方法2;
當只需處理去掉同個對象而不需處理多個鍵值對相同的對象時,能夠採用方法3;
當要求對不一樣對象但鍵值對相同的對象進行去重時,咱們能夠採用方法4。function

原址:http://chanthuang.blog.163.com/blog/static/16812743820133725815167/

相關文章
相關標籤/搜索