尝试从两个List <int>对象</int>中获取不同的值

时间:2010-04-01 15:12:33

标签: .net .net-3.5

我有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等,因为这些列表来自数据库,并且可能长达数百到数千个条目。

谢谢!

6 个答案:

答案 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