如果层次化列表中的项没有子项,则删除该项

本文关键字:删除 列表 如果 层次 | 更新日期: 2023-09-27 18:15:54

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

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

检查我有一个没有条目的用户( user A2),我有一个没有用户的组(Group A2)。

而且,一个更复杂的情况:我有一个门户(门户B),它有一个组( B1组),它有一个用户(用户B1),但是这个用户没有任何项目,所以这个用户(用户B1)它是无效的,但是现在,组B1它也是无效的,因为没有任何用户,所以,门户B1没有任何组。

我怎么做这个列表没有任何子项,像:

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

我可以用很多for, do, while, foreach等来做这个…

但是LINQ有解决方案吗?或者类似的东西?

(代码越短越好)

如果层次化列表中的项没有子项,则删除该项

虽然这段代码"适用于"您的特定场景,但我不建议使用它,因为它非常难读,不能清楚地传达代码的预期目的,会导致本不应该有任何副作用,并且会给其他维护者以后的工作和调试带来痛苦。

Gilad Green的回答更明智:-)

然而,这里有一个版本可以满足您使用 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();

虽然可能,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>() }
};