C# 一次查询多个列表
我有一系列的清单:C# 一次查询多个列表,c#,linq,C#,Linq,我有一系列的清单: List<foo> spamSpamAndSpam; List<foo> spamSpamSpamSausageEggsAndSpam; List<foo> spamSpamSpamSausageEggsBaconAndSpam; List<foo> spamSpamSpamSpamSpamWithoutSpam; List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovel
List<foo> spamSpamAndSpam;
List<foo> spamSpamSpamSausageEggsAndSpam;
List<foo> spamSpamSpamSausageEggsBaconAndSpam;
List<foo> spamSpamSpamSpamSpamWithoutSpam;
List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam;
我正在捕获对所有foo
的引用,其中给定属性(例如,bar
)的值包含在后一个列表中。我是这样做的:
func<foo, bool> deadParrot = x => Brian.Contains(x.bar);
IEnumerable<foo> okLumberjacks = spamSpamAndSpam.Where(deadParrot);
okLumberjacks = okLumberjacks.Concat(
spamSpamSpamSpamSausageEggsAndSpam.Where(deadParrot));
// And so on, concatenating the results of Where() from every list of <foo>.
foreach (foo incontinentRunner in okLumberjacks)
{
incontinentRunner.SillyWalk();
}
所以我的问题是。。。有没有一种方法可以在单个集合中收集每个foo
,而不必求助于以下方法:
ni = ni.Concat(someList.Where(filter));
okLumberjacks = spamSpamAndSpam.
And(spamSpamSpamSausageEggsAndSpam).
And(spamSpamSpamSausageEggsBaconAndSpam) /* etc */ .Where(deadParrot);
var everything = spam1.Concat(spam2).Concat(spam3);
var itemsIWant = everything.Where(x => Brian.Contains(x));
我的意思是,有没有更优雅的方式来处理Linq?我要找的东西是:
ni = ni.Concat(someList.Where(filter));
okLumberjacks = spamSpamAndSpam.
And(spamSpamSpamSausageEggsAndSpam).
And(spamSpamSpamSausageEggsBaconAndSpam) /* etc */ .Where(deadParrot);
var everything = spam1.Concat(spam2).Concat(spam3);
var itemsIWant = everything.Where(x => Brian.Contains(x));
或者更好:
okLumberjacks = spanishInquisition.Where(deadParrot);
// Where the type of spanishInquisition is List<List<foo>>.
okLumberjacks=spanishInquisition.Where(死鹦鹉);
//其中,搜索类型为列表。
我不想修改
foo
的原始列表,因为我需要它们,因为它们用于以后代码中的另一个操作。创建列表列表,然后将其展平:
List<List<foo>> lists = new List<List<foo>>()
{
spamSpamAndSpam,
spamSpamSpamSausageEggsAndSpam,
//etc.
};
IEnumerable<foo> items = lists.SelectMany(item => item);
//do stuff with items.
列表列表=新列表()
{
垃圾邮件,
spamspamspamspamsausageggsandspam,
//等等。
};
IEnumerable items=列表。选择many(item=>item);
//处理物品。
我能想到的最好的方法是:
ni = ni.Concat(someList.Where(filter));
okLumberjacks = spamSpamAndSpam.
And(spamSpamSpamSausageEggsAndSpam).
And(spamSpamSpamSausageEggsBaconAndSpam) /* etc */ .Where(deadParrot);
var everything = spam1.Concat(spam2).Concat(spam3);
var itemsIWant = everything.Where(x => Brian.Contains(x));
Union()能解决您的问题吗
List<foo> spamSpamAndSpam;
List<foo> spamSpamSpamSausageEggsAndSpam;
List<foo> spamSpamSpamSausageEggsBaconAndSpam;
List<foo> spamSpamSpamSpamSpamWithoutSpam;
List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam;
var x = spamSpamAndSpam
.Union(spamSpamSpamSausageEggsAndSpam)
.Union(spamSpamSpamSausageEggsBaconAndSpam)
.Union(spamSpamSpamSausageEggsBaconAndSpam)
.Union(spamSpamSpamSpamSpamWithoutSpam)
.Union(spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam)
.Where(x => ..... );
列出垃圾邮件和垃圾邮件;
列出垃圾邮件pamspamsausageeggsandspam;
列出SPAMSPAMSPAMSAUSAGEEGSBACONANDSPAM;
列出SPAMSPAMSPAMSPAMSPAMWITHOUTPAM;
列出spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam;
var x=SpamPamandSpam
.Union(spamspamspamspamsausageeggsandspam)
.Union(spamSpamSpamSausageEggsBaconAndSpam)
.Union(spamSpamSpamSausageEggsBaconAndSpam)
.Union(SPAMSPAMSPAMSPAMWITHOUTSPAM)
.Union(SPAMSPAMSPAMSPAMSPAMSPAMSPAMSPAMLOVELYSPAMWONDERFULSPAM)
.式中(x=>…);
注意:正如正确指出的那样,从返回集中排除重复项。这与方法不同,它返回输入序列中的所有元素,包括重复项。由于重复排除不是一个要求,Concat可能更好代码中所有类型的
调用都不起作用;您已经有一个指定类型的IEnumerable
,所以它只是一个noop。@这是一个很好的观点。但我正在使用Sharepoint。。。它的集合类都没有实现IEnumerable
,也没有公开Where
扩展方法,但它们都公开了类型的,我对Linq是新手。我编辑该问题是为了删除of type
+1,以获得比我在SO问题中想象的更多的Monty Python引用。在您的示例中,您在列表
对象上调用它,这些对象都实现了IEnumerable
。如果对象本身不是列表,但实际上是实现IEnumerable
但不是IEnumerable
的一些其他集合类型,则使用of type
是合适的。而不是嵌套Concat
操作,您可以链接它们以获得更简单的语法:first.Concat(second).Concat(third).Concat(第四);
@Servy:谢谢……我知道有些东西看起来很奇怪。我不知道为什么我一直不去尝试……我原以为它会改变原始列表,但我刚刚测试了一下,我发现它没有改变。+1。@RenanAddRange
是List
的等效运算符,它正在变异。很好。这就是我一直在寻找的:)也是。谢谢,这个问题让我学到了很多。回到家后,我将重新阅读每个扩展方法的文档。Union将删除重复项,他没有将其作为明确的目标。如果没有重复,那么你就浪费时间/精力/内存来检查它们Concat
实际上与Union
相同,但没有dup检查,似乎是这里更合适的运算符。@很高兴知道。但是复制是用相等运算符测试的,对吗?因此,具有相同属性值的两个对象仍将作为不同的对象进行计算,对吗?@Renan等式将通过EqualityComparer.Default
确定。如果您没有覆盖IEquatable
接口或Equals
和GetHashCode
方法(来自对象),那么它将使用引用比较,而不是成员比较。如果你推翻了其中的一个,它会做你在那里做的一切。@galets旁注,你不应该以问题的形式表达你的答案。如果你想把你的答案作为一个答案来贴,那就把它作为一个答案来贴。