我有2个List对象:
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);
我需要得到一个包含这两者的“不同”列表的对象;所以在这种情况下,返回将是List {2,3}。
有一种简单的方法吗?或者我是否需要遍历列表中的每个值并进行比较?
我愿意使用ObjectQuery,LINQ等,因为这些列表来自数据库,并且可能长达数百到数千个条目。
谢谢!
答案 0 :(得分:13)
Ahmad与Except
几乎是对的,我相信 - 但这不会为您提供lst2
但不在lst1
中的项目。因此,在您给出的示例中,如果您向lst2
添加了5,我想您希望结果为{2,3,5}。在这种情况下,您需要对称差异。我没有认为在单个调用中有任何方法可以直接在LINQ to Objects中执行此操作,但您仍然可以实现它。这是一种简单但效率低下的方法:
lst1.Union(lst2).Except(lst1.Intersect(lst2)).ToList();
(如果您真的需要ToList()
而不是List<T>
,显然您只需IEnumerable<T>
。)
阅读本文的方法是“我想要列在任何一个列表中的项目,但不要同时在两个列表中。”
使用Concat
可能会更有效率 - 这仍然可行,因为Except
是基于集合的运算符,只会返回不同的结果:
lst1.Concat(lst2).Except(lst1.Intersect(lst2)).ToList();
答案 1 :(得分:6)
编辑:感谢您除了使用Except
获得对称差异之外,还需要做一些额外的工作。如果向第二个列表添加了附加值,则除了单独的值之外。要获得正确的结果,请尝试以下方法:
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<int>
,否则上述操作将返回IEnumerable<int>
。
使用Enumerable.Except method,它产生两个序列的集合差异:
var result = lst1.Except(lst2);
答案 2 :(得分:1)
如果结果来自数据库,最好在那里处理它们。与内存操作相比,它会快得多,特别是如果有很多结果的话。
如果您必须在代码中处理它们,可以使用i4o - Indexed LINQ使其更快。
答案 3 :(得分:0)
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。
答案 4 :(得分:0)
就是那个 -
var distinct = a.Union(b);
答案 5 :(得分:-1)
在Linq:
var distinct = lst2.Contact(lst1).Distinct().ToList();
(您的解释似乎表明您希望两个列表中都包含唯一元素。但您的示例似乎需要两个列表的union
。