2011-10-07 59 views
3

我想比較多陣列和結合任何相同:的Javascript:比較三個數組

A = [1,2,3]; 
B = [1,2,3]; 
C = [1,2,3]; 

D = [10,11,12]; 
E = [10,11,12]; 
F = [10,11,12]; 

G = [13,14]; 
H = [13,14]; 

如果有相同的陣列,然後我想創建新的陣列出相同的國家:

I = [1,2,3]; 
J = [10,11,12]; 
K = [13,14]; 

我需要遍歷一個數組中的每個元素對其他數組中的所有元素嗎?

for (var i in A) { 
    for (var j in B) { 
     if (A[i] == J[j]) { 
      // create new arrays 
     } 
    } 
} 

等等

然後,創建新的陣列出來的比賽嗎?聽起來像很多開銷。

完成此操作的最佳方法是什麼?

謝謝!

+0

for-in迭代對象鍵。它不是* for-each循環,你不應該在數組中使用它。 – hugomg

+0

@missingno評論很好,但試圖解釋爲什麼不應該使用或不提供鏈接。謝謝。 – JsusSalv

+0

我應該更加明確。數組除了索引之外還有其他屬性(您真正關心的),而且for-in也可以迭代它們(除非您的瀏覽器一直保護您)。如果你決定在某一天使用改變Array.prototype的庫,如MooTools或Prototype,那麼這是特別危險的,並且突然出現大量虛假的東西出現在你的循環中。要迭代一個數組,你應該使用一個簡單的for-loop或者一個迭代方法,比如.forEach(如果你的瀏覽器/庫支持的話) – hugomg

回答

5

如果你只是想用獨特的陣列完成了,我會使用散列法:

var myArrays = [A,B,C,D,E,F,G], 
    uniques = [], 
    hashes = {}; 

for (var i=0; i < myArrays.length; i++) { 
    var hash = JSON.stringify(myArrays[i]); // or .toString(), or whatever 
    if (!(hash in hashes)) { 
     hashes[hash] = true; 
     uniques.push(myArrays[i]); 
    } 
} 
// uniques now holds all unique arrays 
+0

除一種情況外,仍然有一些問題可以解決。瘋狂,我知道,但事情就是這樣。你能提供一個很好的jsFiddle例子嗎? – JsusSalv

+0

這裏你去:http://jsfiddle.net/nrabinowitz/L4Ekx/1/。我在'for'循環中輸入了一個錯誤 - 'var i;'應該是'var i = 0;'。以上更正。 – nrabinowitz

+0

sweeet !!謝謝! – JsusSalv

0

我相信是這樣,但起碼你可以使用一個比較陣列功能,使其更容易,即使它只是慢:

function compareArrays(arr1,arr2) 
{ 
    if (arr1.length != arr2.length) return false; 
    for (var i = 0; i < arr2.length; i++) 
    { 
     if (arr1[i].compareArrays) 
     { //likely nested arr2ay 
      if (!arr1[i].compareArrays(arr2[i])) return false; 
      else continue; 
     } 
     if (arr1[i] != arr2[i]) return false; 
    } 
    return true; 
} 

然後,你只需要使用此功能,你循環訪問數組。

+0

我想說明的是,我在其他地方(可能在Stackoverflow上)但我早已忘記了在哪裏。 –

1

根據您對相同的定義,您可以轉換爲字符串並進行比較。

if (A.toString() == B.toString()) { //combine } 
1

嗯...我會做這樣

function combine(arr1, arr2) 
{ 
    if(arr1.join(',') === arr2.join(',')) 
     return arr1; 
} 

或許多陣列

function combine(arrList) 
{ 
    var pass = true; 
    var compareArray = arrList[0]; 
    for(var i in arrList) 
     pass = pass && (arrList[i].join(',') === compareArray.join(',')); 
    if(pass) 
     return compareArray; 
} 

arr = combine([[1,2,3],[1,2,3],[1,2,3]]); // results in [1,2,3] 
+0

這仍然需要你做1-1所有可能的組合比較... – nrabinowitz

+0

@nrabinowitz我不明白它是否有任何不同於列出的任何其他方法。即使在你的數組中,它也會循環多少次。唯一的區別是你的存儲在一個對象中。你也有可能進行多重比較(散列部分中的散列),使它與存在的數組數量相比更多(例如,對於5個數組,它可能會進行8次比較)。在這種情況下,我只會進行5次比較,如果我優化了它,甚至是4次。 –

+0

我只比較散列,而不是數組。我的版本是O(n) - 對於5個數組,它使5個哈希對象查找。也許我錯過了關於你的版本的東西 - 我只是沒有看到你的方法如何獲得一個數組列表和結果的唯一數組列表,我認爲這是OP想要的。 – nrabinowitz

1

如果你是ju比較原始數組的數組或字符串,比方說,你可以比較它們的字符串表示形式。

function simpleArrayMatch(A,B){ 
    return String{A)===String(B); 
} 
+0

我很好奇這個功能。你能把它衝出來多一點,以便我可以看到它的工作環境? – JsusSalv

+0

沒有jsFiddle樣本?適用於一組數組,但是多重呢? – JsusSalv

1

假設你有內部的每個數組是數字或只是文本,所以這也許沒有經過任何陣列循環一個可行的辦法:

(見小提琴here

代碼:

A = [1,2,3]; 
B = [1,2,3]; 
C = [1,2,3]; 

D = [10,11,12]; 
E = [10,11,12]; 
F = [10,11,12]; 

G = [13,14]; 
H = [13,14]; 

function compareArr(arrList){ 
    var S = '@' + arrList.join('@'); 
    var re = /(@[^@]+)(@.*)?(\1)(@|$)/gi 
    var afterReplace=''; var i=0; 
    while(afterReplace!=S && i<100){ 
     afterReplace=S; 
     S = S.replace(re, "$1$2$4") 
     i++ 
    } 

    return S.substr(1,S.length-1).replace(/@/g,'<br>') 
} 

$('html').append(compareArr([A,B,C,D,E,F,G,H])) 

策略是將所有數組連接成一個字符串,並以「@」作爲分隔符。然後使用正則表達式來替換所有重複的內部字符串,最後分割字符串,然後你有列表中的唯一數組。

在我的代碼中使用while循環的原因僅僅是因爲我無法寫出更好的正則表達式來一次刪除重複的塊。尋找更好的正則表達式?

+0

巧妙!謝謝。 – JsusSalv