it-swarm.asia

Bagaimana cara membandingkan array dalam JavaScript?

Saya ingin membandingkan dua array ... idealnya, efisien. Tidak ada yang mewah, hanya true jika mereka identik, dan false jika tidak. Tidak mengherankan, operator perbandingan sepertinya tidak berfungsi.

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 melakukan encoding pada setiap array, tetapi apakah ada cara yang lebih cepat atau "lebih baik" untuk hanya membandingkan array tanpa harus beralih melalui setiap nilai?

762
Julian H. Lam

Untuk membandingkan array, mengulanginya dan membandingkan setiap nilai: 

Membandingkan array:

// Warn if overriding existing method
if(Array.prototype.equals)
    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// 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;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

Pemakaian:

[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;

Anda bisa mengatakan "Tapi jauh lebih cepat untuk membandingkan string - tanpa loop ..." baik, maka Anda harus mencatat ada loop. Loop rekursif pertama yang mengubah Array menjadi string dan kedua, yang membandingkan dua string. Jadi metode ini lebih cepat daripada penggunaan string.

Saya percaya bahwa jumlah data yang lebih besar harus selalu disimpan dalam array, bukan pada objek. Namun jika Anda menggunakan objek, mereka juga dapat dibandingkan.
Begini caranya:

Membandingkan objek:

Saya telah menyatakan di atas, bahwa dua objek instance tidak akan pernah sama, walaupun mereka berisi data yang sama saat ini:

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

Ini memiliki alasan, karena mungkin ada, misalnya variabel pribadi dalam objek.

Namun, jika Anda hanya menggunakan struktur objek untuk memuat data, perbandingan masih dimungkinkan:

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;
}  

Namun, ingat bahwa ini adalah untuk melayani dalam membandingkan JSON seperti data, bukan instance kelas dan hal-hal lainnya. Jika Anda ingin membandingkan objek yang lebih rumit, lihat jawaban ini dan fungsinya sangat panjang .
Untuk membuat ini berfungsi dengan Array.equals Anda harus mengedit sedikit fungsi asli:

...
    // 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]) {
...

Saya membuat alat uji kecil untuk kedua fungsi .

Bonus: Array bersarang dengan indexOf dan contains

Samy Bencherif telah menyiapkan fungsi yang berguna untuk kasus Anda mencari objek tertentu dalam array bersarang, yang tersedia di sini: https://jsfiddle.net/SamyBencherif/8352y6yw/

780
Tomáš Zato

Meskipun ini hanya berfungsi untuk array skalar (lihat catatan di bawah), ini singkat:

array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})

Rr, dalam ECMAScript 6/CoffeeScript/TypeScript dengan Fungsi Panah:

array1.length === array2.length && array1.every((value, index) => value === array2[index])

(Catatan: 'skalar' di sini berarti nilai yang dapat dibandingkan secara langsung menggunakan ===. Jadi: angka, string, objek dengan referensi, fungsi dengan referensi. Lihat referensi MDN untuk info lebih lanjut tentang operator perbandingan).

PERBARUI

Dari apa yang saya baca dari komentar, mengurutkan array dan membandingkan dapat memberikan hasil yang akurat:

array1.length === array2.length && array1.sort().every(function(value, index) { return value === array2.sort()[index]});

Misalnya:

array1 = [2,3,1,4];
array2 = [1,2,3,4];

Maka kode di atas akan memberikan true

286
user2782196

Saya suka menggunakan perpustakaan Garis Bawah untuk proyek pengkodean array/objek berat ... di Garis Bawah dan Lodash apakah Anda membandingkan array atau objek, tampilannya hanya seperti ini:

_.isEqual(array1, array2)   // returns a boolean
_.isEqual(object1, object2) // returns a boolean
170
Jason Boerner

Ini menurut saya adalah cara paling sederhana untuk melakukannya menggunakan JSON stringify, dan ini mungkin solusi terbaik dalam beberapa situasi:

JSON.stringify(a1) === JSON.stringify(a2);

Ini mengubah objek a1 dan a2 menjadi string sehingga mereka dapat dibandingkan. Urutan penting dalam banyak kasus, untuk itu dapat mengurutkan objek menggunakan algoritma pengurutan yang ditunjukkan pada salah satu jawaban di atas.

Harap dicatat bahwa Anda tidak lagi membandingkan objek tetapi representasi string objek. Mungkin tidak persis seperti yang Anda inginkan.

81
radtek

Tidak jelas apa yang Anda maksud dengan "identik". Sebagai contoh, apakah array a dan b di bawah ini sama (perhatikan array bersarang)?

var a = ["foo", ["bar"]], b = ["foo", ["bar"]];

Berikut adalah fungsi perbandingan array yang dioptimalkan yang membandingkan elemen yang sesuai dari setiap array pada gilirannya menggunakan kesetaraan yang ketat dan tidak melakukan perbandingan berulang dari elemen array yang merupakan array itu sendiri, yang berarti bahwa untuk contoh di atas, arraysIdentical(a, b) akan mengembalikan false. Ini berfungsi dalam kasus umum, yang tidak akan didasarkan pada solusi JSON- dan join()-:

function arraysIdentical(a, b) {
    var i = a.length;
    if (i != b.length) return false;
    while (i--) {
        if (a[i] !== b[i]) return false;
    }
    return true;
};
61
Tim Down

Dalam semangat pertanyaan awal:

Saya ingin membandingkan dua array ... idealnya, efisien. Tidak ada suka, hanya benar jika mereka identik, dan salah jika tidak.

Saya telah menjalankan tes kinerja pada beberapa saran yang lebih sederhana yang diusulkan di sini dengan hasil (cepat ke lambat) berikut:

while (67%) oleh Tim Down

var i = a1.length;
while (i--) {
    if (a1[i] !== a2[i]) return false;
}
return true

every (69%) oleh user2782196

a1.every((v,i)=> v === a2[i]);

kurangi (74%) oleh DEIs

a1.reduce((a, b) => a && a2.includes(b), true);

gabung & toString (78%) oleh Gaizka Allende & vivek

a1.join('') === a2.join('');

a1.toString() === a2.toString();

setengah toString (90%) oleh Victor Palomo

a1 == a2.toString();

stringify (100%) oleh radtek

JSON.stringify(a1) === JSON.stringify(a2);

Catatan contoh di bawah ini mengasumsikan array diurutkan, array satu dimensi. Perbandingan .length telah dihapus untuk tolok ukur umum (tambahkan a1.length === a2.length ke salah satu saran dan Anda akan mendapatkan peningkatan kinerja ~ 10%). Pilih solusi apa pun yang paling sesuai untuk Anda mengetahui kecepatan dan keterbatasan masing-masing.

Catatan yang tidak berhubungan: menarik untuk melihat orang-orang mendapatkan semua pemicu-senang John Waynes pada tombol pilihan turun pada jawaban sah untuk pertanyaan ini. 

35
unitario

Membangun jawaban Tomáš Zato, saya setuju bahwa hanya mengulangi melalui array adalah yang tercepat. Selain itu (seperti yang telah dinyatakan orang lain), fungsi tersebut harus disebut sama dengan/sama, bukan membandingkan. Mengingat hal ini, saya memodifikasi fungsi untuk menangani membandingkan array untuk kesamaan - yaitu mereka memiliki elemen yang sama, tetapi tidak sesuai - untuk penggunaan pribadi, dan saya pikir saya akan melemparkannya ke sini untuk dilihat semua orang.

Array.prototype.equals = function (array, strict) {
    if (!array)
        return false;

    if (arguments.length == 1)
        strict = true;

    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i], strict))
                return false;
        }
        else if (strict && this[i] != array[i]) {
            return false;
        }
        else if (!strict) {
            return this.sort().equals(array.sort(), true);
        }
    }
    return true;
}

Fungsi ini mengambil parameter tambahan ketat yang standarnya menjadi true. Parameter ketat ini mendefinisikan jika array harus sepenuhnya sama di kedua konten dan urutan konten tersebut, atau hanya cukup berisi konten yang sama.

Contoh:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3];  // Loosely equal to 1
var arr3 = [2, 2, 3, 4];  // Not equal to 1
var arr4 = [1, 2, 3, 4];  // Strictly equal to 1

arr1.equals(arr2);         // false
arr1.equals(arr2, false);  // true
arr1.equals(arr3);         // false
arr1.equals(arr3, false);  // false
arr1.equals(arr4);         // true
arr1.equals(arr4, false);  // true

Saya juga telah menulis jsfiddle cepat dengan fungsi dan contoh ini:
http://jsfiddle.net/Roundaround/DLkxX/

28

Meskipun ini memiliki banyak jawaban, salah satu yang saya yakin dapat membantu:

const newArray = [ ...new Set( [...arr1, ...arr2] ) ]

Tidak disebutkan dalam pertanyaan bagaimana struktur array akan terlihat seperti, jadi Jika Anda tahu pasti bahwa Anda tidak akan memiliki array atau objek bersarang dalam array Anda (itu terjadi pada saya, itu sebabnya saya, Saya sampai pada jawaban ini) kode di atas akan berfungsi.

Yang terjadi adalah kami menggunakan operator spread (...) untuk menyatukan kedua array, lalu kami menggunakan Set untuk menghilangkan duplikat apa pun. Setelah Anda memilikinya, Anda dapat membandingkan ukurannya, jika ketiga array memiliki ukuran yang sama, Anda dapat melakukannya.

Jawaban ini juga mengabaikan urutan elemen, seperti yang saya katakan, situasi yang tepat terjadi pada saya, jadi mungkin seseorang dalam situasi yang sama mungkin berakhir di sini (seperti yang saya lakukan).


Edit1.

Menjawab pertanyaan Dmitry Grinko: "Mengapa Anda menggunakan operator spread (...) di sini - ... Perangkat baru? Tidak berfungsi"

Pertimbangkan kode ini:

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

Anda akan mendapatkannya

[ Set { 'a', 'b', 'c' } ]

Untuk bekerja dengan nilai itu, Anda perlu menggunakan beberapa properti Set (lihat https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set ) . Di sisi lain, ketika Anda menggunakan kode ini:

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

Anda akan mendapatkannya

[ 'a', 'b', 'c' ]

Itulah bedanya, yang pertama akan memberi saya Set, itu akan bekerja juga karena saya bisa mendapatkan ukuran Set itu, tetapi yang terakhir memberi saya array yang saya butuhkan, apa yang lebih langsung ke resolusi.

8

Pada baris yang sama dengan JSON.encode adalah menggunakan join ().

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    //slice so we do not effect the original
    //sort makes sure they are in order
    //join makes it a string so we can do a string compare
    var cA = arrA.slice().sort().join(","); 
    var cB = arrB.slice().sort().join(",");

    return cA===cB;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];  //will return true

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //true

Satu-satunya masalah adalah jika Anda peduli tentang jenis yang diuji perbandingan terakhir . Jika Anda peduli tentang jenis, Anda harus mengulang.

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;

    //slice so we do not effect the orginal
    //sort makes sure they are in order
    var cA = arrA.slice().sort(); 
    var cB = arrB.slice().sort();

    for(var i=0;i<cA.length;i++){
         if(cA[i]!==cB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false

Jika urutannya harus tetap sama, daripada hanya satu lingkaran, tidak ada jenis yang diperlukan.

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    for(var i=0;i<arrA.length;i++){
         if(arrA[i]!==arrB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,a) );  //true
console.log( checkArrays(a,b) );  //false
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false
7
epascarello

Jika hanya dua array angka atau string, ini adalah satu baris cepat

const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false

const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true
6
Gaizka Allende

untuk array dimensi tunggal Anda cukup menggunakan:

arr1.sort().toString() == arr2.sort().toString()

ini juga akan menangani array dengan indeks tidak cocok.

5
Vivek

Jika Anda menggunakan kerangka kerja pengujian seperti Mocha dengan perpustakaan pernyataan Chai , Anda bisa menggunakan deep kesetaraan untuk membandingkan array.

expect(a1).to.deep.equal(a2)

Ini harus mengembalikan true hanya jika array memiliki elemen yang sama di indeks yang sesuai.

5
metakermit

Ini adalah versi TypeScript:

//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
    if (a === b) return true
    if (a == null || b == null) return false
    if (a.length != b.length) return false

    for (var i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) return false
    }
    return true
}

//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
    return JSON.stringify(a) === JSON.stringify(b)
}

Beberapa test case untuk moka:

it('arraysEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','Apple','banana']
    let f = ['car','Apple','banana']
    let g = ['car','Apple','banan8']

    expect(arraysEqual(a, b)).to.equal(true)
    expect(arraysEqual(c, d)).to.equal(true)
    expect(arraysEqual(a, d)).to.equal(false)
    expect(arraysEqual(e, f)).to.equal(true)
    expect(arraysEqual(f, g)).to.equal(false)
})

it('arraysDeepEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','Apple','banana']
    let f = ['car','Apple','banana']
    let g = ['car','Apple','banan8']
    let h = [[1,2],'Apple','banan8']
    let i = [[1,2],'Apple','banan8']
    let j = [[1,3],'Apple','banan8']

    expect(arraysDeepEqual(a, b)).to.equal(true)
    expect(arraysDeepEqual(c, d)).to.equal(true)
    expect(arraysDeepEqual(a, d)).to.equal(false)
    expect(arraysDeepEqual(e, f)).to.equal(true)
    expect(arraysDeepEqual(f, g)).to.equal(false)
    expect(arraysDeepEqual(h, i)).to.equal(true)
    expect(arraysDeepEqual(h, j)).to.equal(false)
})
4
Esqarrouth

Ini membandingkan 2 array yang tidak disortir:

function areEqual(a, b) {
  if ( a.length != b.length) {
    return false;
  }
  return a.filter(function(i) {
    return !b.includes(i);
  }).length === 0;  
}

Inilah solusi saya:

/**
 * Tests two data structures for equality
 * @param {object} x
 * @param {object} y
 * @returns {boolean}
 */
var equal = function(x, y) {
    if (typeof x !== typeof y) return false;
    if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
    if (typeof x === 'object') {
        for (var p in x) if (x.hasOwnProperty(p)) {
            if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
            if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
            if (typeof x[p] !== typeof y[p]) return false;
            if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
            if (x[p] !== y[p]) return false;
        }
    } else return x === y;
    return true;
};

Bekerja dengan struktur data bersarang, dan jelas mengabaikan metode objek. Jangan pernah berpikir untuk memperluas Object.prototype dengan metode ini, ketika saya mencoba ini sekali, jQuery rusak;)

Untuk sebagian besar array masih lebih cepat daripada sebagian besar solusi serialisasi. Ini mungkin metode perbandingan tercepat untuk array dari catatan objek.

3
Harry

Kita dapat melakukan ini dengan cara fungsional, menggunakan every ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every )

function compareArrays(array1, array2) {
    if (array1.length === array2.length)
        return array1.every((a, index) => a === array2[index])
    else
        return false
}

// test
var a1 = [1,2,3];
var a2 = [1,2,3];

var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']

console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false
3
peonicles
var a1 = [1,2,3,6];
var a2 = [1,2,3,5];

function check(a, b) {
  return (a.length != b.length) ? false : 
  a.every(function(row, index) {
    return a[index] == b[index];
  });
}  

check(a1, a2);

////// OR ///////

var a1 = [1,2,3,6];
var a2 = [1,2,3,6];

function check(a, b) {
  return (a.length != b.length) ? false : 
  !(a.some(function(row, index) {
    return a[index] != b[index];
  }));
}  

check(a1, a2)
2
Vasanth

Membandingkan 2 array:

var arr1 = [1,2,3];
var arr2 = [1,2,3];

function compare(arr1,arr2)
{
  if((arr1 == arr2) && (arr1.length == arr2.length))
    return true;
  else
    return false;
}

fungsi panggilan

var isBool = compare(arr1.sort().join(),arr2.sort().join());
1
Amay Kulkarni

Pilih masing-masing dari [a] dan lewati semua dari [b]: Hasil: 1, 5

var a = [1,4,5,9];
var b = [1,6,7,5];

for (i = 0; i < a.length; i++) {
    for (z = 0; z < a.length; z++) {
        if (a[i] === b[z]) {
            console.log(b[z]); // if match > console.log it 
        }
    }
}
1
jclobro

Alasannya adalah identitas atau operator ketat (===), itu membandingkan tanpa konversi jenis, yang berarti jika kedua nilai tidak memiliki nilai yang sama dan jenis yang sama, mereka tidak akan dianggap sama.

lihat tautan ini, ini membuat Anda ragu cara mudah untuk memahami cara kerja operator identitas

1
ludico8

skrip ini membandingkan Objek, Array, dan larik multidimensi

function compare(a,b){
     var primitive=['string','number','boolean'];
     if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
     if(typeof a!==typeof b || a.length!==b.length)return false;
     for(i in a){
          if(!compare(a[i],b[i]))return false;
     }
     return true;
}

baris pertama memeriksa apakah itu tipe primitif. jika demikian itu membandingkan dua parameter.

jika mereka Objects. iterates atas Object dan memeriksa setiap elemen secara berulang. 

Pemakaian:

var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b);  //true
1
Omar Elawady

Fungsi ini membandingkan dua array yang bentuknya sewenang-wenang dan dimesionalitas:

function equals(a1, a2) {

    if (!Array.isArray(a1) || !Array.isArray(a2)) {
        throw new Error("Arguments to function equals(a1, a2) must be arrays.");
    }

    if (a1.length !== a2.length) {
        return false;
    }

    for (var i=0; i<a1.length; i++) {
        if (Array.isArray(a1[i]) && Array.isArray(a2[i])) {
            if (equals(a1[i], a2[i])) {
                continue;
            } else {
                return false;
            }
        } else {
            if (a1[i] !== a2[i]) {
                return false;
            }
        }
    }

    return true;
}
1
chessweb

Dalam kasus saya, array yang dibandingkan hanya berisi angka dan string. Fungsi ini akan menunjukkan kepada Anda jika array mengandung elemen yang sama.

function are_arrs_match(arr1, arr2){
    return arr1.sort().toString() === arr2.sort().toString()
}

Ayo kita coba!

arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]

console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false
1
yesnik

Memperluas ide Tomáš Zato. Tomas's Array.prototype.compare harus benar bernama Array.prototype.compareIdentical.

Itu lewat:

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

Tetapi gagal pada:

[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])

Berikut ini versi yang lebih baik (menurut saya):

Array.prototype.compare = 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;

    this.sort();
    array.sort();
    for (var i = 0; i < this.length; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].compare(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;
}

http://jsfiddle.net/igos/bcfCY/

1
Igor S.

Pendekatan lain dengan sedikit kode (menggunakan Array mengurangi dan Array meliputi ):

arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true)

Jika Anda ingin membandingkan juga kesetaraan pesanan:

arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true)
  • Pemeriksaan length memastikan bahwa set elemen dalam satu array bukan hanya subset dari array lainnya.

  • Peredam digunakan untuk berjalan melalui satu array dan mencari setiap item dalam array lain. Jika satu item tidak ditemukan, fungsi pengurangan mengembalikan false

    1. Dalam contoh pertama sedang diuji bahwa suatu elemen disertakan
    2. Contoh kedua memeriksa pesanan juga
1
DEls
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ?  array.Push(collection[i]) : null

Beginilah cara saya melakukannya.

1
Leed

Dengan opsi untuk membandingkan pesanan atau tidak:

function arraysEqual(a1, a2, compareOrder) {
    if (a1.length !== a2.length) {
        return false;
    }

    return a1.every(function(value, index) {
        if (compareOrder) {
            return value === a2[index];
        } else {
            return a2.indexOf(value) > -1;
        }
    });
}
0
Lacho Tomov

Rekursif & bekerja padaBERSARANGarray:

function ArrEQ(a1,a2){
   return( 
        //:Are both elements arrays?
        Array.isArray(a1)&&Array.isArray(a2) 
        ?
        //:Yes: Test each entry for equality:
        a1.every((v,i)=>(ArrEQ(v,a2[i])))
        :
        //:No: Simple Comparison:
        (a1===a2)
   );;
};;

console.log( "Works With Nested Arrays:" );
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]],
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]]
));;     
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"DIFFERENT:APPLES" ]]],
    [1,2,3,[4,5,[6,"DIFFERENT:ORANGES"]]]
));;  
0
J.M.I. MADISON

Pendekatan sederhana:

function equals(a, b) {
    if ((a && !b) || (!a && b) || (!a && !b) || (a.length !== b.length)) {
        return false;
    }

    var isDifferent = a.some(function (element, index) { 
        return element !== b[index];
    });

    return !isDifferent;
}
0
Pedro Rodrigues

Solusi saya membandingkan Objek, bukan Array. Ini akan bekerja dengan cara yang sama dengan Tomáš's sebagai Array adalah Objects, tetapi tanpa Peringatan:

Object.prototype.compare_to = function(comparable){

    // Is the value being compared an object
    if(comparable instanceof Object){

        // Count the amount of properties in @comparable
        var count_of_comparable = 0;
        for(p in comparable) count_of_comparable++;

        // Loop through all the properties in @this
        for(property in this){

            // Decrements once for every property in @this
            count_of_comparable--;

            // Prevents an infinite loop
            if(property != "compare_to"){

                // Is the property in @comparable
                if(property in comparable){

                    // Is the property also an Object
                    if(this[property] instanceof Object){

                        // Compare the properties if yes
                        if(!(this[property].compare_to(comparable[property]))){

                            // Return false if the Object properties don't match
                            return false;
                        }
                    // Are the values unequal
                    } else if(this[property] !== comparable[property]){

                        // Return false if they are unequal
                        return false;
                    }
                } else {

                    // Return false if the property is not in the object being compared
                    return false;
                }
            }
        }
    } else {

        // Return false if the value is anything other than an object
        return false;
    }

    // Return true if their are as many properties in the comparable object as @this
    return count_of_comparable == 0;
}

Semoga ini bisa membantu Anda atau siapa pun yang mencari jawaban.

0
user1877408

Fungsi cmp Récursive bekerja dengan angka/string/array/objek

<script>
var cmp = function(element, target){

   if(typeof element !== typeof target)
   {
      return false;
   }
   else if(typeof element === "object" && (!target || !element))
   {
      return target === element;
   }
   else if(typeof element === "object")
   {
       var keys_element = Object.keys(element);
       var keys_target  = Object.keys(target);
       
       if(keys_element.length !== keys_target.length)
       {
           return false;
       }
       else
       {
           for(var i = 0; i < keys_element.length; i++)
           {
                if(keys_element[i] !== keys_target[i])
                    return false;
                if(!cmp(element[keys_element[i]], target[keys_target[i]]))
                    return false;
           }
                   return true;
       }
   }
   else
   {
           return element === target;

   }
};

console.log(cmp({
    key1: 3,
    key2: "string",
    key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
}, {
    key1: 3,
    key2: "string",
    key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
})); // true

console.log(cmp({
    key1: 3,
    key2: "string",
    key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
}, {
    key1: 3,
    key2: "string",
    key3: [4, "45", {key4: [5, "6", undefined, null, {v:1}]}]
})); // false
</script>
0
Daphoque

mencoba sedalam-dalamnya dan berhasil

var eq = require('deep-equal');
eq({a: 1, b: 2, c: [3, 4]}, {c: [3, 4], a: 1, b: 2});
0
d9k
function compareArrays(arrayA, arrayB) {
    if (arrayA.length != arrayB.length) return true;
    for (i = 0; i < arrayA.length; i++)
        if (arrayB.indexOf(arrayA[i]) == -1) {
            return true;
        }
    }
    for (i = 0; i < arrayB.length; i++) {
        if (arrayA.indexOf(arrayB[i]) == -1) {
            return true;
        }
    }
    return false;
}
0
macki

Bekerja denganMULTIPLEargumen denganNESTEDarray:

//:Return true if all of the arrays equal.
//:Works with nested arrays.
function AllArrEQ(...arrays){
    for(var i = 0; i < (arrays.length-1); i++ ){
        var a1 = arrays[i+0];
        var a2 = arrays[i+1];
        var res =( 
            //:Are both elements arrays?
            Array.isArray(a1)&&Array.isArray(a2) 
            ?
            //:Yes: Compare Each Sub-Array:
            //:v==a1[i]
            a1.every((v,i)=>(AllArrEQ(v,a2[i])))
            :
            //:No: Simple Comparison:
            (a1===a2)
        );;
        if(!res){return false;}
    };;
    return( true );
};;

console.log( AllArrEQ( 
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
));; 
0
J.M.I. MADISON

Saya telah menggunakan: untuk bergabung dengan array dan membuat string untuk membandingkan . Untuk skenario yang kompleks dari contoh ini Anda dapat menggunakan beberapa pemisah lainnya.

var a1 = [1,2,3];
var a2 = [1,2,3];
if (a1.length !== a2.length) {
   console.log('a1 and a2 are not equal')
}else if(a1.join(':') === a2.join(':')){
   console.log('a1 and a2 are equal')
}else{
   console.log('a1 and a2 are not equal')
}
0
Manoj Yadav

Meskipun jawaban teratas untuk pertanyaan ini benar dan baik, kode yang diberikan dapat menggunakan beberapa peningkatan.

Di bawah ini adalah kode saya sendiri untuk membandingkan array dan objek. Kode ini pendek dan sederhana:

Array.prototype.equals = function(otherArray) {
  if (!otherArray || this.length != otherArray.length) return false;
  return this.reduce(function(equal, item, index) {
    var otherItem = otherArray[index];
    var itemType = typeof item, otherItemType = typeof otherItem;
    if (itemType !== otherItemType) return false;
    return equal && (itemType === "object" ? item.equals(otherItem) : item === otherItem);
  }, true);
};

if(!Object.prototype.keys) {
  Object.prototype.keys = function() {
    var a = [];
    for (var key in this) {
      if (this.hasOwnProperty(key)) a.Push(key);
    }
    return a;
  }
  Object.defineProperty(Object.prototype, "keys", {enumerable: false});
}

Object.prototype.equals = function(otherObject) {
  if (!otherObject) return false;
  var object = this, objectKeys = object.keys();
  if (!objectKeys.equals(otherObject.keys())) return false;
  return objectKeys.reduce(function(equal, key) {
    var value = object[key], otherValue = otherObject[key];
    var valueType = typeof value, otherValueType = typeof otherValue;
    if (valueType !== otherValueType) return false;
    // this will call Array.prototype.equals for arrays and Object.prototype.equals for objects
    return equal && (valueType === "object" ? value.equals(otherValue) : value === otherValue);
  }, true);
}
Object.defineProperty(Object.prototype, "equals", {enumerable: false});

Kode ini mendukung array bersarang di objek dan objek bersarang di array.

Anda dapat melihat serangkaian pengujian lengkap dan menguji sendiri kodenya di repl ini: https://repl.it/Esfz/3

0
Mator

Ini adalah versi CoffeeScript, untuk mereka yang lebih suka:

Array.prototype.equals = (array) ->
  return false if not array # if the other array is a falsy value, return
  return false if @length isnt array.length # compare lengths - can save a lot of time

  for item, index in @
    if item instanceof Array and array[index] instanceof Array # Check if we have nested arrays
      if not item.equals(array[index]) # recurse into the nested arrays
        return false
    else if this[index] != array[index]
      return false # Warning - two different object instances will never be equal: {x:20} != {x:20}
  true

Semua kredit diberikan ke @ tomas-zato.

0
Martin

Sebenarnya, dalam dokumentasi Lodash , mereka memberikan dua contoh yang cukup bagus untuk membandingkan dan mengembalikan array baru untuk perbedaan dan kesamaan (masing-masing dalam contoh di bawah):

import { differenceWith, intersectionWith, isEqual } from 'lodash'

differenceWith(
  [{ a: 1 }, { b: 1 }],
  [{ a: 1 }, { b: 1 }, { c: 1 }],
  isEqual
) // []... ????the bigger array needs to go first!

differenceWith(
  [{ a: 1 }, { b: 1 }, { c: 1 }],
  [{ a: 1 }, { b: 1 }],
  isEqual,
) // [{ c: 1 }] ????

intersectionWith(
  [{ a: 1 }, { b: 1 }],
  [{ a: 1 }, { b: 1 }, { c: 1 }],
  isEqual,
) // [{ a: 1 }, { b: 1 }] ????this one doesn't care about which is bigger

Jika Anda tidak akan selalu tahu array mana yang akan lebih besar, Anda dapat menulis fungsi pembantu untuk itu seperti ini:

const biggerFirst = (arr1, arr2) => {
  return arr1.length > arr2.length ? [arr1, arr2] : [arr2, arr1]
}

const [big, small] = biggerFirst(
  [{ a: 1 }, { b: 1 }],
  [{ a: 1 }, { b: 1 }, { c: 1 }],
)

differenceWith(big, small, isEqual) // ????even though we have no idea which is bigger when they are fed to biggerFirst()

Dari apa yang bisa saya katakan, ini sangat cocok sehingga sangat bagus.

Saya tahu mengandalkan perpustakaan untuk semuanya tidak harus bertepuk tangan, tetapi ini adalah solusi paling ringkas/bersih yang saya temukan untuk masalah yang sangat umum. Semoga ini bisa membantu seseorang!

0
corysimmons

Ini cara yang sangat singkat untuk melakukannya

function arrEquals(arr1, arr2){
     arr1.length == arr2.length && 
     arr1.filter(elt=>arr2.includes(elt)).length == arr1.length
}
0

Sudah beberapa jawaban yang bagus. Tetapi saya ingin berbagi ide anter yang telah terbukti andal dalam membandingkan array. Kita dapat membandingkan dua array menggunakan JSON.stringify () . Ini akan membuat string keluar dari array dan dengan demikian membandingkan dua string yang diperoleh dari dua array untuk kesetaraan

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:1},2]) //true

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},2]) //false

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:1},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //true

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[4]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[5]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //true
0
AL-zami

Jika array sederhana dan urutannya penting maka dua baris ini dapat membantu

//Assume
var a = ['a','b', 'c']; var b = ['a','e', 'c'];  

if(a.length !== b.length) return false;
return !a.reduce(
  function(prev,next,idx, arr){ return prev || next != b[idx] },false
); 

Mengurangi berjalan melalui salah satu array dan mengembalikan 'false' jika setidaknya satu elemen 'a' juga tidak sama dengan elemen 'b' Hanya membungkus ini ke dalam fungsi 

0
Serge