2011-10-07 71 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