У меня есть два массива. Например:
int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};
Каков наилучший способ определить, имеют ли они одни и те же элементы?
У меня есть два массива. Например:
int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};
Каков наилучший способ определить, имеют ли они одни и те же элементы?
Используя LINQ, вы можете реализовать его выразительно и результативно:
var q = from a in ar1
join b in ar2 on a equals b
select a;
bool equals = ar1.Length == ar2.Length && q.Count() == ar1.Length;
Вы также можете использовать SequenceEqual
, если сначала отсортированы объекты IEnumerable.
int[] a1 = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] a2 = new[] { 9, 1, 4, 5, 2, 3, 6, 7, 8 };
bool equals = a1.OrderBy(a => a).SequenceEqual(a2.OrderBy(a => a));
Будут ли значения всегда уникальными? Если да, то как насчет (после проверки равной длины):
var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);
Используйте методы расширения (новые в 3.0). Если длина пересечения двух массивов равна объему их объединения, тогда массивы равны.
bool equals = arrayA.Intersect(arrayB).Count() == arrayA.Union(arrayB).Count()
Succinct.
Для наиболее эффективного подхода (Reflectored из кода Microsoft), см. Stack вопрос переполнения Сравнение двух коллекций для равенства независимо от порядка элементов в них.
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
В Framework 4.0 представлен интерфейс IStructuralEquatable, который помогает сравнивать типы, такие как массивы или кортежи:
class Program
{
static void Main()
{
int[] array1 = { 1, 2, 3 };
int[] array2 = { 1, 2, 3 };
IStructuralEquatable structuralEquator = array1;
Console.WriteLine(array1.Equals(array2)); // False
Console.WriteLine(structuralEquator.Equals(array2, EqualityComparer<int>.Default)); // True
// string arrays
string[] a1 = "a b c d e f g".Split();
string[] a2 = "A B C D E F G".Split();
IStructuralEquatable structuralEquator1 = a1;
bool areEqual = structuralEquator1.Equals(a2, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Arrays of strings are equal:"+ areEqual);
//tuples
var firstTuple = Tuple.Create(1, "aaaaa");
var secondTuple = Tuple.Create(1, "AAAAA");
IStructuralEquatable structuralEquator2 = firstTuple;
bool areTuplesEqual = structuralEquator2.Equals(secondTuple, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Are tuples equal:" + areTuplesEqual);
IStructuralComparable sc1 = firstTuple;
int comparisonResult = sc1.CompareTo(secondTuple, StringComparer.InvariantCultureIgnoreCase);
Console.WriteLine("Tuples comarison result:" + comparisonResult);//0
}
}
Я нашел решение подробно здесь, чтобы быть очень чистым способом, хотя для некоторых людей немного много.
Лучше всего, что он работает и для других IEnumerables.
Это проверит, что каждый массив содержит одинаковые значения в порядке.
int[] ar1 = { 1, 1, 5, 2, 4, 6, 4 };
int[] ar2 = { 1, 1, 5, 2, 4, 6, 4 };
var query = ar1.Where((b, i) => b == ar2[i]);
Assert.AreEqual(ar1.Length, query.Count());
public static bool ValueEquals(Array array1, Array array2)
{
if( array1 == null && array2 == null )
{
return true;
}
if( (array1 == null) || (array2 == null) )
{
return false;
}
if( array1.Length != array2.Length )
{
return false;
}
if( array1.Equals(array2))
{
return true;
}
else
{
for (int Index = 0; Index < array1.Length; Index++)
{
if( !Equals(array1.GetValue(Index), array2.GetValue(Index)) )
{
return false;
}
}
}
return true;
}