2012-06-07 13 views
52

Jaki jest najszybszy/najlepszy sposób porównania dwóch tablic i zwrócenia różnicy? Podobnie jak array_diff w PHP. Czy istnieje prosta funkcja, czy też muszę ją utworzyć za pomocą each()? lub pętlę foreach?Porównaj 2 tablice zwracające różnicę

+0

Cześć, człowieku, myślę, że możesz użyć 'inArray' i zapełnić różnicę między 2 tablice; Wkleiłem dla ciebie działające demo, mam nadzieję, że pomoże B-) –

+0

duplikat http://stackoverflow.com/questions/1187518/javascript-array-difference (nawet jeśli był już gdzieś tam gdzieś połączony) – cregox

+0

Ty prawdopodobnie chcę [ta odpowiedź z poprzedniego pytania SO] (http://stackoverflow.com/a/4026828/304588). Bazuje na prototypie Array. –

Odpowiedz

60

Praca demohttp://jsfiddle.net/u9xES/

Dobry Link (jQuery Documentation): http://docs.jquery.com/Main_Page {można wyszukać lub API przeczytać tutaj}

nadzieję, że to pomoże Ci, jeśli szukasz, aby zrobić to w jQuery.

Alert na końcu wyświetla tablicę nietypowego elementu Tablica, czyli różnicę między 2 tablicami.

Proszę lemme wiedzieć, jeśli coś przeoczyłem, okrzyki!

Kod

var array1 = [1, 2, 3, 4, 5, 6]; 
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 
var difference = []; 

jQuery.grep(array2, function(el) { 
     if (jQuery.inArray(el, array1) == -1) difference.push(el); 
}); 

alert(" the difference is " + difference);​ // Changed variable name 
+8

Ta metoda jest fajna, ale powinna uwzględnić przypadek, gdy długość tablicy 2 jest mniejsza niż tablica1 –

+14

Bardziej elegancka: po prostu 'różnica = $ .grep (a1, funkcja (x) {return $ .inArray (x, a2) <0}) ' –

+2

Świetna odpowiedź. Jednak chciałbym podkreślić, że używasz '.grep' takich jak' .each'; powinno być 'differe = $ .grep (array2, function (el) {return $ .inArray (el, tablica1) == -1;})' – PeterKA

1

Takie operacje na macierze nie są najmocniejszą stroną jQuery. Powinieneś rozważyć bibliotekę taką jak Underscorejs, a konkretnie funkcję różnicową.

3
var arrayDiff = function (firstArr, secondArr) { 
    var i, o = [], fLen = firstArr.length, sLen = secondArr.length, len; 


    if (fLen > sLen) { 
     len = sLen; 
    } else if (fLen < sLen) { 
     len = fLen; 
    } else { 
     len = sLen; 
    } 
    for (i=0; i < len; i++) { 
     if (firstArr[i] !== secondArr[i]) { 
      o.push({idx: i, elem1: firstArr[i], elem2: secondArr[i]}); //idx: array index 
     } 
    } 

    if (fLen > sLen) { // first > second 
     for (i=sLen; i< fLen; i++) { 
      o.push({idx: i, 0: firstArr[i], 1: undefined}); 
     } 
    } else if (fLen < sLen) { 
     for (i=fLen; i< sLen; i++) { 
      o.push({idx: i, 0: undefined, 1: secondArr[i]}); 
     } 
    }  

    return o; 
}; 
127

wiem, jest to stara sprawa, ale myślałem, że chciałbym podzielić się tą małą sztuczkę.

var diff = $(old_array).not(new_array).get(); 

diff zawiera teraz, co było w old_array że nie jest w new_array

+2

krótkie i słodkie .. tak jak lubię to .. użyłem tego z '$ .merge()', aby połączyć różnice w specyficznej określonej kolejności ... – kingkode

+1

czy to zadziała, jeśli tablica zawiera obiekty? Próbuję porównać obiekty w dwóch tablicach. – Batman

+2

Oto scenariusz. Działa to dobrze dla '$ (['h', 'h', 'h', 'h', 'h']). Not ($ ([" a "," a "," a "]))' ale dla tablicy takiej jak '$ (['h', 'h', 'h', 'h', 'h']). not ($ ([" a "," a "," a "," h "]))) (UWAGA ostatnie" h "w tablicy) zwraca pustą tablicę. Różnica nie jest zwracana. Dlatego jest wadliwy. –

2

jeśli chcesz porównać kolejność odpowiedzi można przedłużyć odpowiedź na coś takiego:

Array.prototype.compareTo = function (array2){ 
    var array1 = this; 
    var difference = []; 
    $.grep(array2, function(el) { 
     if ($.inArray(el, array1) == -1) difference.push(el); 
    }); 
    if(difference.length === 0){ 
     var $i = 0; 
     while($i < array1.length){ 
      if(array1[$i] !== array2[$i]){ 
       return false; 
      } 
      $i++; 
     } 
     return true; 
    } 
    return false; 
} 
2

W ten sposób nie musisz się martwić, czy pierwsza tablica jest mniejsza niż druga.

var arr1 = [1, 2, 3, 4, 5, 6,10], 
    arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 

function array_diff(array1, array2){ 
    var difference = $.grep(array1, function(el) { return $.inArray(el,array2) < 0}); 
    return difference.concat($.grep(array2, function(el) { return $.inArray(el,array1) < 0}));; 
} 

console.log(array_diff(arr1, arr2)); 
8

użycie podkreślenia jak:

_.difference(array1,array2) 
+1

Nie daje to odpowiedzi na pytanie. Aby skrytykować lub poprosić o wyjaśnienie od autora, pozostaw komentarz pod swoim postem. – AlSki

+2

@AlSki daje odpowiedź na zadane pytanie! porównuje dwie tablice i zwraca różnicę. –

+1

@ anurag_29 Pytanie brzmiało, jak to zrobić z jQuery, a nie podkreśleniem. – reergymerej

2
/** SUBTRACT ARRAYS **/ 
function subtractarrays(array1, array2){ 
    var difference = []; 
    for(var i = 0; i < array1.length; i++) { 
     if($.inArray(array1[i], array2) == -1) { 
        difference.push(array1[i]); 
     } 
    } 

    return difference; 
} 

Następnie można wywołać funkcję gdziekolwiek w kodzie.

var I_like = ["love", "sex", "food"]; 
var she_likes = ["love", "food"]; 

alert("what I like and she does't like is: " + subtractarrays(I_like, she_likes)); //returns "Naughty"! 

Działa to we wszystkich przypadkach i pozwala uniknąć problemów z powyższymi metodami. Mam nadzieję, że pomaga!

0

Powinno to działać z nieposortowanymi tablicami, podwójnymi wartościami i różnymi rzędami oraz długością, jednocześnie przekazując przefiltrowane wartości z postaci tablica1, tablica2 lub obie.

function arrayDiff(arr1, arr2) { 
    var diff = {}; 

    diff.arr1 = arr1.filter(function(value) { 
     if (arr2.indexOf(value) === -1) { 
      return value; 
     } 
    }); 

    diff.arr2 = arr2.filter(function(value) { 
     if (arr1.indexOf(value) === -1) { 
      return value; 
     } 
    }); 

    diff.concat = diff.arr1.concat(diff.arr2); 

    return diff; 
}; 

var firstArray = [1,2,3,4]; 
var secondArray = [4,6,1,4]; 

console.log(arrayDiff(firstArray, secondArray)); 
console.log(arrayDiff(firstArray, secondArray).arr1); 
// => [ 2, 3 ] 
console.log(arrayDiff(firstArray, secondArray).concat); 
// => [ 2, 3, 6 ] 
0

Zamiast ciągnąć cały Lodash, możesz użyć tego lekkiego komponentu open source o rozdzielczości array-diff.

przykład:

diff([1,2,3], [1,2,3,4,5]) // => [4,5] 

Działa on przez concating dwóch tablic wykonane i filtrowanie zawarte Vals powrotem tablicę reprezentującą różnicę między dwoma macierzami.

Powiązane problemy