Di Jawa, Arrays.equals()
memungkinkan untuk dengan mudah membandingkan konten dua array dasar (kelebihan tersedia untuk semua tipe dasar).
Apakah ada hal seperti itu di C #? Apakah ada cara "ajaib" untuk membandingkan konten dua array di C #?
Di Jawa, Arrays.equals()
memungkinkan untuk dengan mudah membandingkan konten dua array dasar (kelebihan tersedia untuk semua tipe dasar).
Apakah ada hal seperti itu di C #? Apakah ada cara "ajaib" untuk membandingkan konten dua array di C #?
Jawaban:
Anda bisa menggunakannya Enumerable.SequenceEqual
. Ini berfungsi untuk semua IEnumerable<T>
, bukan hanya array.
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 memeriksa Length
kesetaraan terlebih dahulu, untuk menghindari penghitungan array yang berbeda panjang hanya untuk menghasilkan akhir false
.
Gunakan Enumerable.SequenceEqual
di LINQ .
int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };
Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true
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.
static class StructuralExtensions
{
public static bool StructuralEquals<T>(this T a, T b)
where T : IStructuralEquatable
{
return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
}
public static int StructuralCompare<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)); // False
Console.WriteLine(a.StructuralEquals(b)); // True
}
{
var a = new[] { 1, 3, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.StructuralCompare(b)); // 1
}
a.StructuralCompare(b)
?
Untuk .NET 4.0 dan lebih tinggi, Anda dapat membandingkan elemen dalam array atau tupel melalui penggunaan tipe StructuralComparisons :
object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };
Console.WriteLine (a1 == a2); // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2)); // False (because arrays is reference types)
IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer));
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
Apakah values2 berisi semua nilai yang terkandung dalam values1?
Anda dapat menggunakan metode ekstensi LINQ Enumerable.Except
dan 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.
SequenceEqual
.
Untuk pengujian unit, Anda dapat menggunakan CollectionAssert.AreEqual
sebagai ganti Assert.AreEqual
.
Ini mungkin cara termudah.
Jika Anda ingin menangani null
input dengan anggun, dan mengabaikan urutan item, coba solusi berikut:
static class Extensions
{
public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
{
if (array1 == null && array2 == null)
return true;
if (array1 == null || array2 == null)
return false;
return array1.Count() == array2.Count() && !array1.Except(array2).Any();
}
}
Kode tes terlihat seperti:
class Program
{
static void Main(string[] args)
{
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = new int[] { 3, 2, 1 };
int[] a3 = new int[] { 1, 3 };
int[] a4 = null;
int[] a5 = null;
int[] a6 = new int[0];
Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
Console.WriteLine(a4.ItemsEqual(a5)); // Output: True. No Exception.
Console.WriteLine(a4.ItemsEqual(a3)); // Output: False. No Exception.
Console.WriteLine(a5.ItemsEqual(a6)); // Output: False. No Exception.
}
}
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();
Untuk beberapa aplikasi mungkin lebih baik:
string.Join(",", arr1) == string.Join(",", arr2)
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.
private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2)
=>
ReferenceEquals(arr1, arr2) || (
arr1 != null && arr2 != null &&
arr1.Count == arr2.Count &&
arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i)
);
membandingkan elemen? bagaimana dengan
public void Linq78a()
{
int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p);
if (!bb) Console.WriteLine("Lists are equal (bb)");
else Console.WriteLine("Lists are not equal (bb)");
}
Ganti kondisi (a == b) dengan apa pun yang ingin Anda bandingkan dalam a dan b.
(ini menggabungkan dua contoh dari sampel Linq pengembang MSDN )
true
) dan null
array (akan crash).
Saya melakukan ini di studio visual dan bekerja dengan sempurna; membandingkan array indeks dengan indeks dengan pendek kode ini.
private void compareButton_Click(object sender, EventArgs e)
{
int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 };
int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 };
int correctAnswers = 0;
int wrongAnswers = 0;
for (int index = 0; index < answer.Length; index++)
{
if (answer[index] == exam[index])
{
correctAnswers += 1;
}
else
{
wrongAnswers += 1;
}
}
outputLabel.Text = ("The matching numbers are " + correctAnswers +
"\n" + "The non matching numbers are " + wrongAnswers);
}
hasilnya adalah; Angka yang cocok adalah 7 Angka yang tidak cocok adalah 3
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 dan IStructuralEquatable
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:
bool ArrayEquals<T>(T[] first, T[] second)
{
if (first == second)
return true;
if (first == null || second == null)
return false;
if (first.Length != second.Length)
return false;
for (var i = 0; i < first.Length; i++)
{
if (first[i] != second[i])
return false;
}
return true;
}
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.
null
. Apa maksudmu