Что является самым быстрым (и наименее ресурсоемким) для сравнения двух массивных (> 50 000 элементов) и в результате получается два списка, подобных приведенному ниже:
- элементы, которые отображаются в первом списке, но не во втором
- элементы, которые отображаются во втором списке, но не в первом
В настоящее время я работаю с List или IReadOnlyCollection и решаю эту проблему в запросе linq:
var list1 = list.Where(i => !list2.Contains(i)).ToList();
var list2 = list2.Where(i => !list.Contains(i)).ToList();
Но это не так хорошо, как хотелось бы. Любая идея сделать это быстрее и менее ресурсоемким, поскольку мне нужно обрабатывать много списков?
Equals(object)
и / или реализует,IEquatable<T>
это должно быть хорошо.IEquatable<T>
реализацию илиobject.Equals(object)
метод. Похоже, вы должны создать новый вопрос с минимальным воспроизводимым примером - мы не можем диагностировать вещи в комментариях.Более эффективным было бы использовать
Enumerable.Except
:Этот метод реализован с использованием отложенного выполнения. Это означает, что вы могли бы написать, например:
Это также эффективно, так как он внутренне использует
Set<T>
для сравнения объектов. Он работает, сначала собирая все отдельные значения из второй последовательности, а затем выводит результаты первой, проверяя, что они не были видны ранее.источник
Set<T>
из второй последовательности (то есть полностью повторяется и сохраняется), затем получаются элементы, которые можно добавить из первой последовательности.Where
частично отложено, потому что вlist.Where(x => x.Id == 5)
значении число5
хранится в начале, а не выполняется лениво.Это работает для всех примитивных типов данных. Если вам нужно использовать его на пользовательских объектах, вы должны реализовать
IEqualityComparer
Определяет методы для поддержки сравнения объектов на равенство.
источник
SequenceEqual
простbool
. ОП хочет два списка результатов - и описывает, что они хотят в терминах операций над множествами: «элементы, которые отображаются в первом списке, но не во втором». Там нет никаких признаков того, что порядок имеет значение, в то время как SequenceEqual действительно считают ее актуальной. Похоже, это отвечает на совершенно другой вопрос.Если вы хотите, чтобы результаты не учитывали регистр , сработает следующее:
firstNotSecond
будет содержать b1.dllsecondNotFirst
будет содержать b2.dllисточник
Не для этой проблемы, но вот код для сравнения списков на равные и нет! идентичные объекты:
источник
Except
попробуйте так:
источник
Иногда вам нужно знать , отличаются ли два списка, а не каковы эти различия. В этом случае рассмотрите возможность добавления этого метода расширения в ваш проект. Обратите внимание, что ваши перечисленные объекты должны реализовывать IEquatable!
Использование:
Каким бы ни был
Component
класс, методы, показанные здесь,Car
должны быть реализованы почти одинаково.Очень важно отметить, как мы написали GetHashCode. Для того , чтобы правильно реализовать
IEquatable
,Equals
иGetHashCode
должны работать на свойства экземпляра в логически совместимым способом.Два списка с одинаковым содержимым по-прежнему являются разными объектами и будут создавать разные хэш-коды. Поскольку мы хотим, чтобы эти два списка рассматривались как равные, мы должны позволить
GetHashCode
создать одинаковое значение для каждого из них. Мы можем сделать это путем делегирования хэш-кода каждому элементу в списке и использования стандартного побитового XOR для их объединения. XOR не зависит от порядка, поэтому не имеет значения, сортируются ли списки по-разному. Имеет значение только то, что они содержат только эквивалентные члены.Примечание: странное имя подразумевает тот факт, что метод не учитывает порядок элементов в списке. Если вы заботитесь о порядке элементов в списке, этот метод не для вас!
источник
Я использовал этот код, чтобы сравнить два списка, который имеет миллион записей.
Этот метод не займет много времени
источник
Если нужен только комбинированный результат, это тоже будет работать:
где T - тип элемента списков.
источник
Может быть, это смешно, но у меня работает
string.Join ("", List1)! = string.Join ("", List2)
источник
Я думаю, что это простой и легкий способ сравнить два списка элемент за элементом
источник
Это лучшее решение, которое вы нашли
источник
List<T>
для каждого элемента вlist1
. Также результат вызывается,list3
когда он не являетсяList<T>
.