C# LINQ:如何将内部列表中的项目放入一个列表中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1028605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:54:33  来源:igfitidea点击:

LINQ: How to get items from an inner list into one list?

c#linqlist

提问by Stécy

Having the following classes (highly simplified):

具有以下类(高度简化):

public class Child
{
    public string Label;
    public int CategoryNumber;
    public int StorageId;
}

public class Parent
{
    public string Label;
    public List<Child> Children = new List<Child>();
}

And having the following data:

并有以下数据:

var parents = new List<Parent>();

var parent = new Parent() {Label="P1"};
parent.Children.Add(new Child() {Label="C1", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C2", CategoryNumber=2, StorageId=20});
parents.Add(parent);

parent = new Parent() {Label="P2"};
parent.Children.Add(new Child() {Label="C3", CategoryNumber=1, StorageId=10});
parent.Children.Add(new Child() {Label="C4", CategoryNumber=2, StorageId=30});
parents.Add(parent);

parent = new Parent() {Label="P3"};
parent.Children.Add(new Child() {Label="C5", CategoryNumber=3, StorageId=10});
parent.Children.Add(new Child() {Label="C6", CategoryNumber=2, StorageId=40});
parents.Add(parent);

Now, how would I get a list of children (with CategoryNumber=2) from the list of parents containing at least one child with CategoryNumber = 1 ?

现在,我如何从包含至少一个 CategoryNumber = 1 的孩子的父母列表中获取孩子的列表(CategoryNumber=2)?

I can do the following but it does not appear to be optimal:

我可以执行以下操作,但似乎不是最佳选择:

var validParents = from p in parents
                   where p.Children.Any (c => c.CategoryNumber==1)
                   select p;
var selectedChildren = validParents.Select(p => from c in p.Children 
                                                where c.CategoryNumber == 2
                                                select c);

Here's what I get for selectedChildren:

这是我为 selectedChildren 得到的:

  • IEnumerable<IEnumerable<Child>>
    • IEnumerable<Child>
      • C2 2 20
    • IEnumerable<Child>
      • C4 2 30
  • IEnumerable<IEnumerable<Child>>
    • IEnumerable<Child>
      • C2 2 20
    • IEnumerable<Child>
      • C4 2 30

Is it possible to only have one flat list containing the two children elements instead of two sub-list? How would it translate in LINQ ?

是否可以只有一个包含两个子元素的平面列表而不是两个子列表?它如何在 LINQ 中翻译?

采纳答案by Eric Lippert

Scott's answer is great; I'd just like to point out that you can in fact do this query using query continuation syntax:

Scott的回答很棒;我只想指出,您实际上可以使用查询继续语法来执行此查询:

from parent in parents 
where parent.Children.Any (c => c.CategoryNumber==1)
select parent into p
from child in p.Children
where child.CategoryNumber == 2
select child

Notice how the "into" lets you pipe the result of one query into the next query. Pretty slick, eh?

请注意“into”如何让您将一个查询的结果通过管道传输到下一个查询中。很圆滑吧?

回答by Scott Ivey

You can string a couple queries together, using SelectManyand Where.

您可以使用SelectManyWhere将几个查询串在一起。

var selectedChildren = (from p in parents
                       where p.Children.Any (c => c.CategoryNumber==1)
                       select p)
                       .SelectMany(p => p.Children)
                       .Where(c => c.CategoryNumber == 2);

// or...

var selectedChildren = parents
                         .Where(p => p.Children.Any(c => c.CategoryNumber == 1))
                         .SelectMany(p => p.Children)
                         .Where(c => c.CategoryNumber == 2);