SORU
20 EKİM 2011, PERŞEMBE


Javascript ile karşılaştırarak iki dizi

İki diziyi karşılaştırmak için... ideal olarak, verimli bir şekilde istiyorum. Eğer aynı iseler hiçbir şey fantezi, sadece true false değilse. Şaşırtıcı olmayan bir şekilde, karşılaştırma operatörü iş gibi görünmüyor.

var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2);    // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2));    // Returns true

JSON her dizi yok kodlama, ama bir ya da daha hızlı "" en basit yolu, her bir değer arasında dolaşmak zorunda kalmadan dizi karşılaştırmak için mi iyi?

CEVAP
13 ŞUBAT 2013, ÇARŞAMBA


Gerçekten bu kadar çok insan karşılaştırmak istiyorum inanamıyorumdizeleri gibi diziler. Bu eski bir soru olsa da, bu yüzden, katacakdoğruyol diziler karşılaştırma yoluyla döngü ve her değeri karşılaştırmak için:

Doğru yol:

// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time 
    if (this.length != array.length)
        return false;

    for (var i = 0, l=this.length; i < l; i  ) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].equals(array[i]))
                return false;       
        }           
        else if (this[i] != array[i]) { 
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;   
        }           
    }       
    return true;
}   

Kullanımı:

[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;

Diyebilirsiniz "Ama çok daha hızlı dizeleri - döngüler karşılaştırın . /^"Peki, o zaman döngüler VARDIR dikkat etmelisiniz.>em İlk dize ve ikinci Dizi dönüştüren, iki dizeleri karşılaştırır döngü özyinelemeli. Bu yöntem o kadarstring . kullanımı daha hızlı.

Veri miktarı arttıkça her zaman nesneleri, diziler, saklı olması gerektiğine inanıyorum. Ancak eğer nesneleri kullanırsanız, kısmen de karşılaştırılabilir.
İşte nasıl:

Nesnelerin karşılaştırılması:

Bu iki nesne yukarıda ifade ettikörneklerihiç değilse şu anda aynı veri içeriyorsa bile eşit olacaktır:

({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666})  //false

Bu, örneğin private variables within objects. olabilir beri bir nedeni vardır

Eğer sadece nesne yapısı veri içeren kullanırsanız, ancak, karşılaştırma yapmak mümkün olacaktır:

Object.prototype.equals = function(object2) {
    //For the first loop, we only check for types
    for (propName in this) {
        //Check for inherited methods and properties - like .equals itself
        //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
        //Return false if the return value is different
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        //Check instance type
        else if (typeof this[propName] != typeof object2[propName]) {
            //Different types => not equal
            return false;
        }
    }
    //Now a deeper check using other objects property names
    for(propName in object2) {
        //We must check instances anyway, there may be a property that only exists in object2
            //I wonder, if remembering the checked values from the first loop would be faster or not 
        if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
            return false;
        }
        else if (typeof this[propName] != typeof object2[propName]) {
            return false;
        }
        //If the property is inherited, do not check any more (it must be equa if both objects inherit it)
        if(!this.hasOwnProperty(propName))
          continue;

        //Now the detail check and recursion

        //This returns the script back to the array comparing
        /**REQUIRES Array.equals**/
        if (this[propName] instanceof Array && object2[propName] instanceof Array) {
                   // recurse into the nested arrays
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
                   // recurse into another objects
                   //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \"" propName "\"");
           if (!this[propName].equals(object2[propName]))
                        return false;
        }
        //Normal value comparison for strings and numbers
        else if(this[propName] != object2[propName]) {
           return false;
        }
    }
    //If everything passed, let's say YES
    return true;
}  

Ancak, bu veri, sınıf örnekleri ve diğer şeyler gibi değil JSON karşılaştırırken hizmet etmek olduğunu unutmayın. Eğer mor karmaşık nesneleri karşılaştırmak istiyorsanız, this answer and it's superlong function bak.
Bu Array.equals ile çalışmak için kendi özgün işlevi biraz düzenlemeniz gerekir:

...
    // Check if we have nested arrays
    if (this[i] instanceof Array && array[i] instanceof Array) {
        // recurse into the nested arrays
        if (!this[i].equals(array[i]))
            return false;
    }
    /**REQUIRES OBJECT COMPARE**/
    else if (this[i] instanceof Object && array[i] instanceof Object) {
        // recurse into another objects
        //console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \"" propName "\"");
        if (!this[i].equals(array[i]))
            return false;
        }
    else if (this[i] != array[i]) {
...

little test tool for both of the functions yaptım.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • eHow

    eHow

    27 NİSAN 2006
  • Jason Rosolowski

    Jason Rosolo

    25 EKİM 2006
  • Tomas N

    Tomas N

    14 Kasım 2010