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.
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.
Gunakan Enumerable.SequenceEqualdi 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.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.
SequenceEqual.
Untuk pengujian unit, Anda dapat menggunakan CollectionAssert.AreEqualsebagai ganti Assert.AreEqual.
Ini mungkin cara termudah.
Jika Anda ingin menangani nullinput 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 nullarray (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
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.
Dengan asumsi persamaan array berarti kedua array memiliki elemen yang sama pada indeks yang sama, ada SequenceEqualjawabannya dan IStructuralEquatablejawabannya .
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:
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