Menambahkan '.net' ke tag karena teknik ini dapat digunakan dalam bahasa berbasis .net yang serupa.
Evan Plaice
3
Untuk semua orang yang membaca ini, perlu diingat bahwa jawaban yang diterima menggunakan SequenceEqual. SequenceEqual tidak hanya memeriksa apakah mereka berisi data yang sama, tetapi juga jika mereka berisi data yang sama dalam urutan yang sama
John Demetriou
Jawaban:
262
Anda bisa menggunakannya Enumerable.SequenceEqual. Ini berfungsi untuk semua IEnumerable<T>, bukan hanya array.
Ini hanya berfungsi jika mereka berada dalam urutan yang sama
John Demetriou
1
SequenceEqualmungkin bukan pilihan kinerja yang baik, karena implementasi saat ini dapat sepenuhnya menyebutkan salah satu sumbernya jika mereka hanya berbeda panjangnya. Dengan array, kita dapat memeriksa Lengthkesetaraan terlebih dahulu, untuk menghindari penghitungan array yang berbeda panjang hanya untuk menghasilkan akhir false.
Perlu diingat bahwa ini melempar argumen nol, jadi pastikan untuk tidak berasumsi bahwanew int[] {1}.SequenceEquals(null) == false
sara
30
Juga untuk array (dan tupel) Anda dapat menggunakan antarmuka baru dari .NET 4.0: IStructuralComparable dan IStructuralEquatable . Dengan menggunakannya, Anda tidak hanya dapat memeriksa persamaan array tetapi juga membandingkannya.
staticclassStructuralExtensions{publicstaticboolStructuralEquals<T>(this T a, T b)where T :IStructuralEquatable{return a.Equals(b,StructuralComparisons.StructuralEqualityComparer);}publicstaticintStructuralCompare<T>(this T a, T b)where T :IStructuralComparable{return a.CompareTo(b,StructuralComparisons.StructuralComparer);}}{var a =new[]{1,2,3};var b =new[]{1,2,3};Console.WriteLine(a.Equals(b));// FalseConsole.WriteLine(a.StructuralEquals(b));// True}{var a =new[]{1,3,3};var b =new[]{1,2,3};Console.WriteLine(a.StructuralCompare(b));// 1}
Sunting: Berbicara terlalu cepat. Bisakah saya melakukan StructualEqualityCompare dengan IStructuralComparable? Saya ingin memanggil CompareTo dengan dua array objek untuk mencari tahu mana yang datang "pertama". Saya mencoba IStructuralComparable se1 = a1; Console.WriteLine (se1.CompareTo (a2, StructuralComparisons.StructuralEqualityComparer)); Mendapatkan: tidak dapat mengonversi dari 'System.Collections.IEqualityComparer' ke 'System.Collections.IComparer'
shindigo
1
OK - panggilan yang benar adalah: IStructuralComparable se1 = a1; Console.WriteLine (se1.CompareTo (a2, StructuralComparisons.StructuralComparer));
shindigo
15
SequenceEqual hanya akan mengembalikan true jika dua syarat atau terpenuhi.
Mereka mengandung elemen yang sama.
Elemen-elemennya berada dalam urutan yang sama.
Jika Anda hanya ingin memeriksa apakah mereka mengandung elemen yang sama terlepas dari pesanan mereka dan masalah Anda adalah tipe
Apakah values2 berisi semua nilai yang terkandung dalam values1?
Anda dapat menggunakan metode ekstensi LINQ Enumerable.Exceptdan kemudian memeriksa apakah hasilnya memiliki nilai. Ini sebuah contoh
int[] values1 ={1,2,3,4};int[] values2 ={1,2,5};var result = values1.Except(values2);if(result.Count()==0){//They are the same}else{//They are different}
Dan juga dengan menggunakan ini Anda mendapatkan item yang berbeda secara otomatis. Dua burung dengan satu batu.
Perlu diingat, jika Anda menjalankan kode Anda seperti ini
var result = values2.Except(values1);
Anda akan mendapatkan hasil yang berbeda.
Dalam kasus saya, saya memiliki salinan lokal array dan ingin memeriksa apakah ada yang telah dihapus dari array asli jadi saya menggunakan metode ini.
Array berisi nilai yang sama dalam urutan yang berbeda, hanya BUKAN SAMA. Apakah Anda menganggap 'Demetriou' == 'uoirtemeD'?
edc65
Itu tergantung. Jika Anda menggunakan array sebagai koleksi yang tidak berurutan dan perlu memeriksa hanya bahwa mereka mengandung elemen yang sama (misalnya, nilai dari database terhadap daftar konfigurasi), maka ini adalah cara termudah yang saya temukan. Jika pesanan itu penting (mis. String), maka Anda akan menggunakannya SequenceEqual.
Armando
11
Untuk pengujian unit, Anda dapat menggunakan CollectionAssert.AreEqualsebagai ganti Assert.AreEqual.
Ini bermanfaat bagi saya, tetapi jika a1 = { 1, 1 }dan a2 = { 1, 2 }, maka tes pertama mengembalikan hasil yang salah. Pernyataan pengembalian harusreturn array1.Count() == array2.Count() && !array1.Except(array2).Any() && !array2.Except(array1).Any();
Solusi LINQ ini berfungsi, tidak yakin bagaimana ia membandingkan kinerja dengan SequenceEquals. Tapi ia menangani panjang array yang berbeda dan. Semua akan keluar pada item pertama yang tidak sama tanpa mengulangi seluruh array.
Itu tidak menangani array dengan panjang yang berbeda (akan crash), nullarray (akan crash juga), dan ia melakukan sesuatu yang lain dari apa yang diminta OP. Dia hanya meminta untuk mengetahui kesetaraan, tanpa menghitung berapa banyak item yang berbeda atau cocok.
Tetapi keduanya memiliki kelemahan, kinerja bijaksana.
SequenceEqual implementasi saat ini tidak akan memendek ketika array memiliki panjang yang berbeda, dan karena itu dapat menghitung satu dari mereka sepenuhnya, membandingkan masing-masing elemen.
IStructuralEquatabletidak generik dan dapat menyebabkan tinju dari setiap nilai yang dibandingkan. Selain itu tidak terlalu mudah untuk digunakan dan sudah memanggil untuk pengkodean beberapa metode pembantu menyembunyikannya.
Mungkin lebih baik, kinerja bijaksana, untuk menggunakan sesuatu seperti:
boolArrayEquals<T>(T[] first, T[] second){if(first == second)returntrue;if(first ==null|| second ==null)returnfalse;if(first.Length!= second.Length)returnfalse;for(var i =0; i < first.Length; i++){if(first[i]!= second[i])returnfalse;}returntrue;}
Tapi tentu saja, itu bukan "cara ajaib" untuk memeriksa persamaan array.
Jadi saat ini, tidak, sebenarnya tidak ada yang setara dengan Java Arrays.equals()di .Net.
Jawaban:
Anda bisa menggunakannya
Enumerable.SequenceEqual
. Ini berfungsi untuk semuaIEnumerable<T>
, bukan hanya array.sumber
SequenceEqual
mungkin bukan pilihan kinerja yang baik, karena implementasi saat ini dapat sepenuhnya menyebutkan salah satu sumbernya jika mereka hanya berbeda panjangnya. Dengan array, kita dapat memeriksaLength
kesetaraan terlebih dahulu, untuk menghindari penghitungan array yang berbeda panjang hanya untuk menghasilkan akhirfalse
.Gunakan
Enumerable.SequenceEqual
di LINQ .sumber
new int[] {1}.SequenceEquals(null) == false
Juga untuk array (dan tupel) Anda dapat menggunakan antarmuka baru dari .NET 4.0: IStructuralComparable dan IStructuralEquatable . Dengan menggunakannya, Anda tidak hanya dapat memeriksa persamaan array tetapi juga membandingkannya.
sumber
a.StructuralCompare(b)
?Untuk .NET 4.0 dan lebih tinggi, Anda dapat membandingkan elemen dalam array atau tupel melalui penggunaan tipe StructuralComparisons :
sumber
SequenceEqual
hanya akan mengembalikan true jika dua syarat atau terpenuhi.Jika Anda hanya ingin memeriksa apakah mereka mengandung elemen yang sama terlepas dari pesanan mereka dan masalah Anda adalah tipe
Anda dapat menggunakan metode ekstensi LINQ
Enumerable.Except
dan kemudian memeriksa apakah hasilnya memiliki nilai. Ini sebuah contohDan juga dengan menggunakan ini Anda mendapatkan item yang berbeda secara otomatis. Dua burung dengan satu batu.
Perlu diingat, jika Anda menjalankan kode Anda seperti ini
Anda akan mendapatkan hasil yang berbeda.
Dalam kasus saya, saya memiliki salinan lokal array dan ingin memeriksa apakah ada yang telah dihapus dari array asli jadi saya menggunakan metode ini.
sumber
SequenceEqual
.Untuk pengujian unit, Anda dapat menggunakan
CollectionAssert.AreEqual
sebagai gantiAssert.AreEqual
.Ini mungkin cara termudah.
sumber
Jika Anda ingin menangani
null
input dengan anggun, dan mengabaikan urutan item, coba solusi berikut:Kode tes terlihat seperti:
sumber
a1 = { 1, 1 }
dana2 = { 1, 2 }
, maka tes pertama mengembalikan hasil yang salah. Pernyataan pengembalian harusreturn array1.Count() == array2.Count() && !array1.Except(array2).Any() && !array2.Except(array1).Any();
Untuk beberapa aplikasi mungkin lebih baik:
sumber
Solusi LINQ ini berfungsi, tidak yakin bagaimana ia membandingkan kinerja dengan SequenceEquals. Tapi ia menangani panjang array yang berbeda dan. Semua akan keluar pada item pertama yang tidak sama tanpa mengulangi seluruh array.
sumber
membandingkan elemen? bagaimana dengan
Ganti kondisi (a == b) dengan apa pun yang ingin Anda bandingkan dalam a dan b.
(ini menggabungkan dua contoh dari sampel Linq pengembang MSDN )
sumber
true
) dannull
array (akan crash).Saya melakukan ini di studio visual dan bekerja dengan sempurna; membandingkan array indeks dengan indeks dengan pendek kode ini.
hasilnya adalah; Angka yang cocok adalah 7 Angka yang tidak cocok adalah 3
sumber
null
array (akan crash juga), dan ia melakukan sesuatu yang lain dari apa yang diminta OP. Dia hanya meminta untuk mengetahui kesetaraan, tanpa menghitung berapa banyak item yang berbeda atau cocok.Dengan asumsi persamaan array berarti kedua array memiliki elemen yang sama pada indeks yang sama, ada
SequenceEqual
jawabannya danIStructuralEquatable
jawabannya .Tetapi keduanya memiliki kelemahan, kinerja bijaksana.
SequenceEqual
implementasi saat ini tidak akan memendek ketika array memiliki panjang yang berbeda, dan karena itu dapat menghitung satu dari mereka sepenuhnya, membandingkan masing-masing elemen.IStructuralEquatable
tidak generik dan dapat menyebabkan tinju dari setiap nilai yang dibandingkan. Selain itu tidak terlalu mudah untuk digunakan dan sudah memanggil untuk pengkodean beberapa metode pembantu menyembunyikannya.Mungkin lebih baik, kinerja bijaksana, untuk menggunakan sesuatu seperti:
Tapi tentu saja, itu bukan "cara ajaib" untuk memeriksa persamaan array.
Jadi saat ini, tidak, sebenarnya tidak ada yang setara dengan Java
Arrays.equals()
di .Net.sumber
null
. Apa maksudmu