如果项目没有子项,则删除分层列表的项目

时间:2016-11-01 18:39:53

标签: c# linq

我有几个属于另一个对象的对象,例如:

class Portal
{
    List<Group> Groups;
}

class Group
{
    List<User> Users;
}

class User
{
    List<Item> Items;
}

class Item
{
    ...
}

现在,假设在调用函数后,我将收到一个列表:

+ Portal A:
  + Group A1:
    + User A1:
      - Item A1
      - Item A2
    + User A2
  + Group A2
+ Portal B
  + Group B1
    + User B1
+ Portal C
  + Group C1
    + User C1
      - Item C1

检查我是否有没有Itens的用户(用户A2 ),并且我有一个没有用户的组(组A2 )。

更复杂的情况:我有一个门户网站(门户网站B ),其中有一个拥有用户的群组(群组B1 )(用户B1 ),但此用户没有任何项目,因此该用户(用户B1 )无效,但现在,组B1 无效因为没有任何用户,所以 Portal B1 没有任何组。

如果没有没有任何孩子的itens,我如何制作这个列表,如:

+ Portal A:
  + Group A1:
    + User A1:
      - Item A1
      - Item A2
+ Portal C
  + Group C1
    + User C1
      - Item C1

我可以用很多for,do,while,foreach等来做到这一点......

但LINQ有一个解决方案吗?或类似的东西?

(代码越短越好)。

2 个答案:

答案 0 :(得分:2)

虽然这段代码&#34;有效&#34;对于您的特定情况,我不建议使用它,因为它非常难以理解,没有清楚地传达代码的预期用途,导致副作用,在那里不应该是任何,并将是一个痛苦供其他维护人员使用以后再进行调试。

Gilad Green's answer更明智: - )

然而,在这里说过这个版本是使用 pure Linq满足您对短缺的需求。

var filteredPortals =
  portals.Where(
    p => (p.Groups = p.Groups.Where(
      g => (g.Users = g.Users.Where(
        u => u.Items.Any()
      ).ToList()).Any()
    ).ToList()).Any()
  ).ToList();

答案 1 :(得分:1)

尽管可能,linq用于查询而不是分配。可读解决方案同时使用foreach和linq。为每个级别循环进入更深层次。在每个级别范围的末尾过滤列表,以仅保留其嵌套循环具有任何项目的项目。

比解释更好的是一些代码:)

foreach (var portal in portals)
{
    foreach (var group in portal.Groups)
    {
        //Keep only users with items
        group.Users = group.Users.Where(user => user.Items.Any()).ToList();
    }
    //Keep only groups with users
    portal.Groups = portal.Groups.Where(group => group.Users.Any()).ToList();
}
//Keep only portals with groups
portals = portals.Where(portal => portal.Groups.Any()).ToList();

使用以下输入进行测试:

List<Portal> portals = new List<Portal>()
{
    //Will keep
    new Portal { Name = "a", Groups = new List<Group>
    {
        //Will keep
        new Group {  Users = new List<User> {  new User {  Items = new List<Item> { new Item()} } } },
        //Filtered
        new Group {  Users = new List<User> {  new User {  Items = new List<Item> () } } }
    } },
    //Will keep
    new Portal { Name = "b", Groups = new List<Group>
    {
        new Group {  Users = new List<User> 
        {  
            //Filtered
            new User {  Items = new List<Item> () },
            //Will keep 
            new User { Items = new List<Item> { new Item() } } 
        } }
    } },
    //Filtered
    new Portal { Groups = new List<Group>() }
};