C# 如何使用LINQ筛选对象列表的列表

C# 如何使用LINQ筛选对象列表的列表,c#,list,linq,C#,List,Linq,我有一个项目列表,每个项目都包含一个组件列表 public class Item { Item(string name) { ItemName = name; } public string ItemName { get; private set; } public List<Component> Components {get;set;} } public class Component { public strin

我有一个项目列表,每个项目都包含一个组件列表

public class Item
{
    Item(string name)
    {
        ItemName = name;
    }
    public string ItemName { get; private set; }
    public List<Component> Components {get;set;}
}

public class Component
{
    public string Name {get;set;}
    public string Status {get;set;}
}

// Example
Item 1
    Component 1 - Status A
    Component 2 - Status B
    Component 3 - Status A
Item 2
    Component 1 - Status C
    Component 2 - Status C
    Component 3 - Status A
Item 3
    Component 1 - Status C
    Component 2 - Status C
    Component 3 - Status D
如果至少有一个组件的状态为A或B,此解决方案将返回包含所有组件的项。在我们的示例中,将返回包含所有组件的项1和项2。结果将是:

Item 1
    Component 1 - Status A
    Component 2 - Status B
    Component 3 - Status A
Item 2
    Component 1 - Status C
    Component 2 - Status C
    Component 3 - Status A
Item 1
    Component 1 - Status A
    Component 2 - Status B
    Component 3 - Status A
Item 2
    Component 3 - Status A
我需要一个类似的解决方案,其结果是:

Item 1
    Component 1 - Status A
    Component 2 - Status B
    Component 3 - Status A
Item 2
    Component 1 - Status C
    Component 2 - Status C
    Component 3 - Status A
Item 1
    Component 1 - Status A
    Component 2 - Status B
    Component 3 - Status A
Item 2
    Component 3 - Status A
仅返回状态为A和B的组件

实现此任务的正确语法是什么

编辑:

根据请求,项目的初始化:

var items = new List<Item>
{
    new Item("Item 1")
    {
        Components = new List<Component>
        {
            new Component {Name ="Component1", Status = "A"},
            new Component {Name ="Component2", Status = "B"},
            new Component {Name ="Component3", Status = "A"}
         }
     },
     new Item("Item 2")
     {
         Components = new List<Component>
         {
            new Component {Name ="Component1", Status = "C"},
            new Component {Name ="Component2", Status = "C"},
            new Component {Name ="Component3", Status = "A"}
         }
     },
     new Item("Item 3")
     {
         Components = new List<Component>
         {
             new Component {Name ="Component1", Status = "C"},
             new Component {Name ="Component2", Status = "C"},
             new Component {Name ="Component3", Status = "D"}
          }
     }
};
var items=新列表
{
新项目(“项目1”)
{
组件=新列表
{
新组件{Name=“Component1”,Status=“A”},
新组件{Name=“Component2”,Status=“B”},
新组件{Name=“Component3”,Status=“A”}
}
},
新项目(“项目2”)
{
组件=新列表
{
新组件{Name=“Component1”,Status=“C”},
新组件{Name=“Component2”,Status=“C”},
新组件{Name=“Component3”,Status=“A”}
}
},
新项目(“项目3”)
{
组件=新列表
{
新组件{Name=“Component1”,Status=“C”},
新组件{Name=“Component2”,Status=“C”},
新组件{Name=“Component3”,Status=“D”}
}
}
};

探索的可能途径:

var statuses = new HashSet<string>() { "A", "B" };
var result = items
    .Where(i => i.Components.Any(c => statuses.Contains(c.Status)))
    .Select(z => new Item(z.ItemName) { Components = z.Components.Where(y => statuses.Contains(y.Status)).ToList() })
    .ToList();
var statuses=newhashset(){“A”,“B”};
var结果=项目
.Where(i=>i.Components.Any(c=>statuses.Contains(c.Status)))
.Select(z=>newitem(z.ItemName){Components=z.Components.Where(y=>statuses.Contains(y.Status)).ToList()
.ToList();

要使其正常工作,您需要将项目构造函数公开。

我只是为了完整起见才将其包括在内(因为我没有足够的声誉来评论)。如果只需要组件而不需要包含项,可以这样做

string[] statuses = { "A", "B" };
var things = items.SelectMany(x => x.Components.Where(y => statuses.Contains(y.Status)));

foreach (var thing in things)
    Console.WriteLine(thing);

如果您可以编写一个简短的C样本来显示您的样本数据的初始化,我们将更快地为您编写一些解决方案。将
.Any(C=>statuses.Contains(C.Status))
更改为
。All(C=>statuses.Contains(C.Status))
。doneSelectMany会做一些技巧来确认。您只需要满足谓词的组件或项及其组件?根据问题的措辞和所示的样本输出,不清楚。这两者似乎有冲突。对不起,我的英语不好,是的,这就是我需要的。示例就是我的意思,不为我工作,会出现一些错误,其中之一是:错误CS0103当前的轻微打字错误中不存在名称“Select”,我很抱歉。现在就试试吧,好好工作