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?
Untuk membandingkan array, mengulanginya dan membandingkan setiap nilai:
// 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});
[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:
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 .
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/
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
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
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.
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;
};
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 (tambahkana1.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.
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/
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.
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
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
untuk array dimensi tunggal Anda cukup menggunakan:
arr1.sort().toString() == arr2.sort().toString()
ini juga akan menangani array dengan indeks tidak cocok.
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)
})
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.
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
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)
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());
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
}
}
}
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
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
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;
}
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
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;
}
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
.
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ? array.Push(collection[i]) : null
Beginilah cara saya melakukannya.
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;
}
});
}
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"]]]
));;
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;
}
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.
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>
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});
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;
}
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" ]]],
));;
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')
}
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
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.
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!
Ini cara yang sangat singkat untuk melakukannya
function arrEquals(arr1, arr2){
arr1.length == arr2.length &&
arr1.filter(elt=>arr2.includes(elt)).length == arr1.length
}
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
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