LINQ в C#: сравнение последовательностей

Иногда, при работе с несколькими коллекциями или последовательностями элементов может потребоваться определить сам факт равенства или неравенства всех элементов в одной коллекции всем элементам во второй коллекции. В этом случае нам нет необходимости выполнять операции Except или Intersect над коллекциями. Для сравнения последовательностей элементов в LINQ используется метод SequenceEqual.

Метод SequenceEqual

Этот метод возвращает True, если две последовательности содержат одинаковое число элементов и каждый очередной элемент из первой коллекции совпадает с каждым очередным элементом во второй коллекции.

Продемонстрировать работу метода SequenceEqual можно на следующем простом примере:

int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int[] ints2 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int[] ints3 = new int[] { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };

string result = ints.SequenceEqual(ints2) ? "Коллекции 1 и 2 совпадают" : "Коллекции 1 и 2 НЕ совпадают";
Console.WriteLine(result);
result = ints2.SequenceEqual(ints3) ? "Коллекции 2 и 3 совпадают" : "Коллекции 2 и 3 НЕ совпадают";
Console.WriteLine(result);

результат выполнения приложения в будет следующим:

Коллекции 1 и 2 совпадают
Коллекции 2 и 3 НЕ совпадают

Несмотря на то, что массив ints3 содержит те же числа, то и массив ints2, метод SequenceEqual вернет false, так как сравнение элементов происходит поочередно — первый элемент первой последовательности сравнивается с первым элементом второй последовательности, второй элемент первой последовательности — со вторым элементом второй последовательности и так далее.

Сравнение последовательностей сложных объектов

Рассмотрим следующий пример:

Person p1 = new Person() { Name = "Вася", Age = 15 };
Person p2 = new Person() { Name = "Петя", Age = 15 };

Person[] people_1 = new Person[] {p1, p2};
Person[] people_2 = new Person[] {p1, p2};

if (people_1.SequenceEqual(people_2))
    Console.WriteLine("Коллекции совпадают");
else
    Console.WriteLine("Коллекции не совпадают");

Здесь обе коллекции содержат по два одинаковых элемента, поэтому результат будет ожидаемым:

Коллекции совпадают

Изменим пример следующим образом:

Person[] people_1 = new Person[] { 
    new Person() { Name = "Вася", Age = 15 },
    new Person() { Name = "Петя", Age = 15 }
};
Person[] people_2 = new Person[] 
{
    new Person() { Name = "Вася", Age = 15 },
    new Person() { Name = "Петя", Age = 15 }
};

if (people_1.SequenceEqual(people_2))
    Console.WriteLine("Коллекции совпадают");
else
    Console.WriteLine("Коллекции не совпадают");

несмотря на то, что, на первый взгляд, элементы последовательностей остались те же, SequenceEqual вернет false, так как при сравнении элементов используется метод Equals(), который проверяет два объекта на равенство, используя для этого ссылки на объект. Поэтому, если мы хотим сравнивать объекты по значениям их свойств, то должны переопределить метод Equals() (и, желательно, GetHashCode). Пример переопределения метода Equals() можно увидеть здесь.

Итого

Метод SequenceEqual удобно использовать в том случае, если нам необходимо установить факт полного соответствия всех элементов одной последовательности всем элементам другой последовательности. Сравнение происходит поэлементно, а при сравнении сложных объектов используется метод object.Equals, который необходимо переопределить, если необходимо сравнивать объекты по их свойствам.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии