2013-04-26 10 views
21

Gegeben zwei Arrays von unterschiedlicher Länge:Compute Kreuzung von zwei Arrays in JavaScript

var arr1 = ["mike", "sue", "tom", "kathy", "henry"]; //arr1.length = 5 
var arr2 = ["howey", "jim", "sue", "jennifer", "kathy", "hank", "alex"]; //arr2.length = 7 

Wie kann ich die Werte, die für beide Arrays finden? In diesem Fall sollten "sue" und "kathy" zurückgegeben werden.

+0

Wollen Sie in diesem Fall Sue und Kathy in Ihren Ergebnissen sein? – ggbranch

+0

Ich suche nach den Übereinstimmungen, richtig. – Justin

Antwort

15

Sie möchten die Schnittmenge zweier Arrays finden?

Sie könnten Underscore intersection() verwenden. Dadurch erhalten Sie eine Liste der in beiden Arrays vorhandenen Werte.

var commonValues = _.intersection(arr1, arr2); 

jsFiddle.

Wenn Sie keine Bibliothek verwenden wollte, wäre es trivial sein ...

var commonValues = arr1.filter(function(value) { 
            return arr2.indexOf(value) > -1; 
           }); 

jsFiddle zu implementieren.

Wenn Array.prototype.filter() und Array.prototype.indexOf() nicht in Ihrer Zielplattform unterstützen ...

var commonValues = []; 
var i, j; 
var arr1Length = arr1.length; 
var arr2Length = arr2.length; 

for (i = 0; i < arr1Length; i++) { 
    for (j = 0; j < arr2Length; j++) { 
     if (arr1[i] === arr2[j]) { 
      commonValues.push(arr1[i]); 
     } 
    } 
} 

jsFiddle.

+0

Dies zu lesen ließ mich anfangen zu denken .. was sollte das erwartete Ergebnis einer Kreuzung sein, wenn Sie "" sue "_multiple mal_ in einem/beiden Arrays erscheinen? –

+0

@PaulS. Interessante Gedanken. Ich denke, das würde es mehrmals hinzufügen, wenn es mehrmals im Quell-Array wäre. Wenn es ein Problem wäre, könnten Sie eine * drop-duplicates * -Typ-Methode für das Ergebnis verwenden (oder den Faktor wie im obigen Code beschrieben). – alex

21

könnten Sie Array.filter verwenden:

var result = arr1.filter(function(n) { 
    return arr2.indexOf(n) > -1; 
}); 
+0

Warum nicht einfach 'arr2.indexOf (n)! == -1' zurückgeben? Sie machen ein neues Array in beide Richtungen. – Blender

+1

@alex filter() gibt Array mit übereinstimmenden Werten zurück, während forEach nichts zurückgibt. –

7

Iterate über eines der Arrays und vergleichen Sie die Objekte mit dem anderen:

var results = []; 

for (var i = 0; i < arr1.length; i++) { 
    if (arr2.indexOf(arr1[i]) !== -1) { 
     results.push(arr1[i]); 
    } 
} 
35

Hier eine Schnittfunktion basierend auf Array.prototype.filter

function intersect(a, b) { 
    var t; 
    if (b.length > a.length) t = b, b = a, a = t; // indexOf to loop over shorter 
    return a.filter(function (e) { 
     return b.indexOf(e) > -1; 
    }); 
} 

var arr1 = ["mike", "sue", "tom", "kathy", "henry"]; 
    arr2 = ["howey", "jim", "sue", "jennifer", "kathy", "hank", "alex"]; 

intersect(arr1, arr2); // ["sue", "kathy"] 

Sie könnten auch die folgenden

var arr1 = ['sue', 'sue', 'kathy'], 
    arr2 = ['kathy', 'kathy', 'sue']; 

Die oben jetzt würde ["sue", "sue", "kathy"] zu betrachten. Wenn du keine Duplikate willst, könntest du einen weiteren Filter dafür machen. Dies würde auch die Ergebnisse standardisieren. das heißt

return a 
    .filter(/* .. */) // same as before 
    .filter(function (e, i, c) { // extra step to remove duplicates 
     return c.indexOf(e) === i; 
    }); 

das Hinzufügen wird nun das gleiche Ergebnis wie die vorherigen Arrays (["sue", "kathy"]) zurückkehren, auch wenn es Duplikate waren.

+1

Danke Paul für die Beseitigung der Duples und regelmäßige Optionen, Nice Bit Code. – JimTheDev

+0

Ich glaube nicht, dass dies funktioniert, wenn eines der beiden Arrays leer ist, wird es eine falsch positive zurückgeben ... Ich habe einfach eine Überprüfung hinzugefügt eine Überprüfung für .Length – afreeland

+6

Arghh .. Ich hasse 'if (Bedingung) zurück wahr; 'Konstruktion .. Warum nicht' Rückkehr Bedingung; '? –

Verwandte Themen