使用 LINQ 我有一个列表列表,如何选择每个列表中存在的所有对象

本文关键字:列表 存在 对象 有一个 LINQ 使用 何选择 选择 | 更新日期: 2023-09-27 18:37:24

>我有一个列表列表:

List<Tuple<string, List<SomeObject>>

我想选择上面列表中所有行中存在的所有SomeObjects

有些只会存在于一个或两个列表中,但我希望每个列表中存在的所有对象,而丢弃其他对象。

如果没有一堆 c# 代码,我无法找到一个优雅的解决方案。有没有好办法?

使用 LINQ 我有一个列表列表,如何选择每个列表中存在的所有对象

list.Select (x => x.Item2 as IEnumerable<SomeObject>)
    .Aggregate((x,y)=> x.Intersect(y))
    .ToList();

或者,正如Jeppe Stig Nielsen所建议的那样(我认为它更优雅):

list.Select(x => x.Item2.AsEnumerable())
    .Aggregate(Enumerable.Intersect)
    .ToList();

正如我正确理解的那样,您需要许多列表的交集:

var results = source.First().Item2
foreach (var element in source.Skip(1) )
{
    results = results.Intersect(element.Item2)
}

受到胡安·洛佩斯(Juan Lopes)美丽答案的强烈启发,您可以定义此扩展:

static IEnumerable<TSource> IntersectMany<TSource>(this IEnumerable<IEnumerable<TSource>> sources)
{
  return sources.Aggregate(Enumerable.Intersect);
}

那么这有效:

var result = list.Select(x => x.Item2).IntersectMany();

它之所以有效IEnumerable<out T>是因为它在T(C# 4、.NET 4.0)中是协变的。

假设该类覆盖Equals + GetHashCode或者您有一个自定义IEqualityComparer<SomeObject>您可以使用以下查询,该查询使用 Enumerable.All

var result = list
    .SelectMany(t => t.Item2)   // select all objects
    .Distinct()                 // just an optimization since duplicates are guaranteed
    .Where(obj => list.All(t => t.Item2.Contains(obj))); 

这是我的示例数据:

var list = new List<Tuple<string, List<SomeObject>>>();
list.Add(Tuple.Create("a", new List<SomeObject> { new SomeObject { ID = 1 }, new SomeObject { ID = 2 }, new SomeObject { ID = 4 } }));
list.Add(Tuple.Create("b", new List<SomeObject> { new SomeObject { ID = 1 }, new SomeObject { ID = 2 }, new SomeObject { ID = 3 } }));
list.Add(Tuple.Create("c", new List<SomeObject> { new SomeObject { ID = 1 }, new SomeObject { ID = 2 }, new SomeObject { ID = 3 } }));
list.Add(Tuple.Create("d", new List<SomeObject> { new SomeObject { ID = 1 }, new SomeObject { ID = 2 }, new SomeObject { ID = 3 } }));
只有 ID =

1 或 ID = 2 的SomeObjects在所有列表中,这是查询的结果。