2013-04-26 25 views
21

Dati due array di lunghezza diversa:Compute intersezione di due array in JavaScript

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

Come posso trovare dei valori comuni a entrambi gli array? In questo caso, è necessario restituire "sue" e "kathy".

+0

Vuoi che Sue e Kathy siano nei tuoi risultati in questo caso? – ggbranch

+0

Sto cercando di trovare le partite, corretto. – Justin

risposta

15

Si desidera trovare l'intersezione di due array?

È possibile utilizzare Underscore's intersection(). Questo ti darà una lista di valori presenti in entrambi gli array.

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

jsFiddle.

Se non si desidera utilizzare una libreria, sarebbe banale da implementare ...

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

jsFiddle.

Se Array.prototype.filter() e Array.prototype.indexOf() non sono supportati nelle piattaforme di destinazione ...

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

Leggere questo mi ha fatto iniziare a pensare .. quale dovrebbe essere il risultato atteso di un incrocio se si ha "causa" che appare _multiplezioni_ in uno/entrambi gli array? –

+0

@PaulS. Pensieri interessanti Immagino che questo lo aggiungerebbe più volte se fosse nell'array sorgente più volte. Se si trattasse di un problema, è possibile utilizzare un metodo di tipo * drop duplicates * sul risultato (o inserirlo come indicato nel codice precedente). – alex

21

Potreste usare Array.filter:

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

Perché non solo 'return arr2.indexOf (n)! == -1'? Stai facendo un nuovo array in entrambi i modi. – Blender

+1

@alex filter() restituisce una matrice di valori corrispondenti, mentre forEach non restituisce nulla. –

7

iterare su una delle matrici e confrontare gli oggetti con l'altra:

var results = []; 

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

Ecco una funzione di incrocio sulla base di 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"] 

Si potrebbe anche prendere in considerazione la seguente

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

È possibile che questo sarebbe ora dare ["sue", "sue", "kathy"]. Se non vuoi duplicati potresti fare un ulteriore filtro su questo. Questo standardizzerebbe anche i risultati. cioè

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

Aggiungendo questo ora tornerà lo stesso risultato come array precedenti (["sue", "kathy"]), anche se c'erano duplicati.

+1

Grazie Paul per aver fornito sia i duplicati di rimozione che le opzioni regolari, Bel po 'di codice. – JimTheDev

+0

Non credo che funzionerà se uno dei due array è vuoto, restituirà un falso positivo ... Ho semplicemente fatto un controllo aggiunto un controllo per .length – afreeland

+6

Arghh .. Odio 'if (condizione) return true; 'costruzione .. Perché non' restituire condizione; '? –

Problemi correlati