如何使用LINQ

时间:2017-06-18 13:15:23

标签: 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 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

使用LINQ,我如何只获得其状态为A或B的组件的所有项目的组件?

以下解决方案不是我想要的:

var statuses = { "A" , "B" }
var result= items
                .Where(i => i.Components
                .Any(c => statuses.Contains(c.Status))
                .ToList();

此解决方案返回包含所有组件的项目,以防至少一个组件具有状态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

仅返回状态为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"}
          }
     }
};

2 个答案:

答案 0 :(得分:2)

探索可能的途径:

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();

为此,您需要将Item构造函数设为公共。

答案 1 :(得分:0)

我只是为了完整而包含这个(因为我没有足够的声誉来评论)。如果你只想要没有包含项目的组件,你可以这样做。

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);