Попытка получить отличные значения из двух Списков <международные> объекты

У меня есть 2 Объекта списка:

List<int> lst1 = new List<int>();
List<int> lst2 = new List<int>();

Скажем, у них есть значения:

lst1.Add(1);
lst1.Add(2);
lst1.Add(3);
lst1.Add(4);

lst2.Add(1);
lst2.Add(4);

Я должен получить объект, содержащий "отличный" список обоих из них; таким образом, в этом случае возврат был бы Списком {2, 3}.

Существует ли простой способ сделать это? Или я должен выполнить итерации через каждое значение списков и выдержать сравнение?

Я открыт для использования ObjectQuery, LINQ, и т.д. когда эти списки прибывают из базы данных и могли потенциально быть несколькими сотнями к нескольким тысячам записей долго.

Спасибо!

8
задан SlackerCoder 1 April 2010 в 15:12
поделиться

6 ответов

Ахмад почти прав с Except, я полагаю - но это не даст вам элементов, которые есть в lst2, но нет в lst1. Поэтому в приведенном вами примере, если вы добавите 5 к lst2, я представляю, что вы хотите получить результат {2, 3, 5}. В этом случае вы хотите получить симметричную разность. Я не думаю, что в LINQ to Objects есть способ сделать это непосредственно за один вызов, но вы все же можете этого добиться. Вот простой, но неэффективный способ сделать это:

lst1.Union(lst2).Except(lst1.Intersect(lst2)).ToList();

(Очевидно, что ToList() нужен только в том случае, если вам действительно нужен List, а не IEnumerable.)

Прочитать это можно так: "Мне нужны элементы, которые есть в любом списке, но не в обоих. "

Возможно, что эффективнее было бы использовать Concat - который все равно будет работать, поскольку Except - это оператор, основанный на множестве, который возвращает только отдельные результаты:

lst1.Concat(lst2).Except(lst1.Intersect(lst2)).ToList();
13
ответ дан 5 December 2019 в 08:51
поделиться

EDIT: благодаря комментариям, чтобы получить симметричную разность, нужно проделать дополнительную работу, кроме использования Except. Если добавить дополнительное значение во 2-й список, то исключение само по себе будет неверным. Чтобы получить правильный результат, попробуйте сделать следующее:

var list1 = new List<int>(Enumerable.Range(1,4));
var list2 = new List<int> { 1, 4, 6 };

var result = list1.Except(list2).Union(list2.Except(list1));

Вышеприведенный результат возвращает {2, 3, 6}.

Обратите внимание, что вам нужно добавить ToList(), если вам действительно нужен List, иначе приведенная выше операция вернет IEnumerable.


Используйте метод Enumerable.Except, который выдает заданную разность двух последовательностей:

var result = lst1.Except(lst2);
6
ответ дан 5 December 2019 в 08:51
поделиться

Если результаты поступают из базы данных, лучше обработать их там. Это будет намного быстрее по сравнению с работой с памятью, особенно если будет много результатов.

Если вам нужно обработать их в своем коде, вы можете использовать i4o - Indexed LINQ , чтобы ускорить процесс.

1
ответ дан 5 December 2019 в 08:51
поделиться

В Linq:

var distinct = lst2.Contact(lst1).Distinct().ToList();

(Из вашего объяснения следует, что вам нужны уникальные элементы в обоих списках. Но из вашего примера следует, что вам нужно объединение обоих списков).

-1
ответ дан 5 December 2019 в 08:51
поделиться

LINQ был бы простым способом, сгруппировав каждый элемент на основе его значения, а затем выбрав только те, которые имеют один элемент:

from i in lst1.Concat(lst2)
group i by i into g
where !g.Skip(1).Any()
select g.Key;

Использование Skip здесь позволит вам убедиться, что существует не более одного элемента; если в последовательности 1 или меньше элементов, возвращается пустая последовательность, для которой Any вернет false.

0
ответ дан 5 December 2019 в 08:51
поделиться

Только что -

var distinct = a.Union(b);
0
ответ дан 5 December 2019 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: