2017-12-06 2 views
2

Ich lerne Javascript, und ich sah eine Funktion auf SO für den Vergleich von Arrays zu überprüfen, ob sie gleich sind. Meine aktuelle Funktion gibt jedoch false zurück, wenn die beiden Arrays [string1, string2] & [string2, string1] sind. Grundsätzlich sind die beiden Positionen vertauscht. Der Code ist wie folgt:Vergleichen von Arrays in Javascript, wo Reihenfolge egal ist

function _compareArrays(arr1,arr2){ 
    var result = arr1 != null && arr2 != null && arr1.length == arr2.length && arr1.every(function(element) { 
      return arr2.indexOf(element); 
     }); 
    return result ; 
} 

Allerdings möchte ich diese beiden Arrays als gleich zurückgegeben werden. Also, ich änderte .every zu .indexOf() und es schien zu funktionieren. Aber ich habe Zweifel, wie genau wird der Zähler hier erhöht, um sicherzustellen, dass der Vergleich für jedes Element durchgeführt wird? Ich meine, wie, in C++, was wir tun,

for (int i = 0; i < 10; i++) 
    if (arr1[i] == arr2[i] 
     cout<<"Elements are same\n"; 

Hier habe ich eine explizite i++, die den Zähler erhöht. Wie läuft es in der obigen Funktion ab?

Danke!

+1

Ihr erster Codeblock ist totaler Quatsch. 'indexOf' nimmt keine Funktion als Argument in irgendeiner Dokumentation, die ich jemals gelesen habe -' Also, ich änderte .every zu .indexOf() 'wenn Sie einen platten Reifen haben, ersetzen Sie das Rad durch eine Banane? –

+0

Ich würde einfach [flache Kopien erstellen] (https://stackoverflow.com/questions/3978492/javascript-fastest-way-to-duplicate-an-array-slice-vs-for-loop) der Arrays, sortieren diese und dann den von Ihnen erwähnten Vergleichsmechanismus verwenden – Phil

+0

Die '_compareArrays' Methode, die Sie definiert haben, gibt immer -1 zurück. Wie die 'every' Methode iteriert, ohne einen Zähler explizit zu inkrementieren: Es ist eine Funktion des Array-Prototyps, die die Iteration automatisch durchführt. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every – nipuna777

Antwort

1

Ihre aktuellen hat diese Probleme:

  1. Es true für diese 2-Arrays zurück (ich hoffe, dass Sie verstehen, dass dies auf diese 2 nicht spezifisch ist): [1, 2, 2], [1,1,2]. Dieses Problem ist, warum ich nach einer Übereinstimmung in meiner Lösung Indizes auf undefined setzen.

  2. indexOf kehrt -1 für Elements kann es nicht finden, und eine beliebige Anzahl >= 0 wenn sie das Element finden, -1 truthy ist, so dass, wenn ein Element nicht gefunden werden kann, Ihr Vergleich true zurück, und 0 ist falsy, also wenn Ein Element befindet sich im ersten Index des zweiten Arrays. Ihre Methode gibt false zurück (was bedeutet, dass das Ganze false wird, wegen every ...). Daher sollten Sie vor dem Ergebnis indexOf einen Anruf ~ hinzufügen: ~arr2.indexOf(element).

    Siehe this MDN-Seite auf dem Bitwise Nicht-Operator (~) und wie es löst das indexOf Problem, das ich erwähnte.

    Ich empfehle auch, dass Sie bei this Antwort von mir auf truthy/falsy Werte einen Blick darauf werfen und wie sie interagieren mit && und ||.


dies also ausprobieren (es ist vor allem Ihr Beispiel, außer es keine indexOf verwendet wird, und ich habe Problem # 2 fest):

function _compareArrays(arr1,arr2){ 
 
    if(!(arr1 != null && arr2 != null && arr1.length == arr2.length)) { 
 
    return false; 
 
    } 
 

 
    /* copy the arrays so that the original arrays are not affected when we set the indices to "undefined" */ 
 
    arr1 = [].concat(arr1); 
 
    arr2 = [].concat(arr2); 
 

 
    return arr1.every(function(element, index) { 
 
    return arr2.some(function(e, i) { 
 
     return e === element && (arr2[i] = undefined, true); 
 
    }); 
 
    }); 
 
} 
 
    
 
var x = ["str", "boo", "str"]; 
 
var y = ["boo", "str", "str"]; 
 
var z = ["abc", "def", "ghi"]  
 

 
console.log(_compareArrays(x, y)); 
 
console.log(_compareArrays(x, z)); 
 
console.log(_compareArrays(z, z));

Es gewann Es funktioniert aber nicht, wenn das Array irgendwelche undefined Elemente hat.

+0

Warum sollten Sie die Werte des Arrays ändern? Ich möchte die Werte beibehalten. – sarah

+0

Sie könnten alle undefinierten Werte am Anfang der Funktion auf null setzen. Aber das wäre ein bisschen janky Lösung. – nipuna777

+1

@sarah Sonst würde [1, 2, 1] als gleich [1, 2, 2] markiert werden – nipuna777

1

Konvertieren Sie das Array stattdessen in ein Objekt. Konvertieren Array-Werte in Schlüssel und ihre jeweilige Anzahl als ihren Wert. Dies ist leistungsfähiger, wenn Sie die Arrays nur einmal durchlaufen.

function compare(a, b) { 
    if (a.length !== b.length) { 
    return false; 
    } 
    let set = {}; 
    a.forEach((i) => { 
    if (set[i] !== undefined) { 
     set[i]++; 
    } else { 
     set[i] = 1; 
    } 
    }); 
    let difference = b.every((i) => { 
    if (set[i] === undefined) { 
     return false; 
    } else { 
     set[i]--; 
     if (set[i] === 0) { 
     delete set[i]; 
     } 
     return true; 
    } 
    }); 
    return Object.keys(set) == 0 && difference; 
} 

Die erste Schleife auf dem ersten Array initialisiert die den Satz (Objekt), die zweite Schleife auf dem zweiten Array subtrahiert den Zählwert und entfernt die Tasten, wenn der Zählwert 0. trifft Wenn ein Schlüssel nicht gefunden wird oder wenn Die Menge ist am Ende der Prozedur nicht leer, dann sind die Arrays nicht ähnlich.

Verwandte Themen