删除树中不包含在路径中的项目

问题描述 投票:0回答:1
public class Item
{
    public string ItemName { get; set; }

    public double Value { get; set; }

    public int Id { get; set; }

    public int ParentId { get; set; }

    public List<Item> Children { get; set; } = new();
}

您好,我的任务是从树中删除所有不必要的项目。

我的团队为我提供了查找具有给定 ItemName 的项目的功能。例如,我将此函数与 ItemName =“Item 11”一起使用。

我的同事告诉我从树上删除所有不必要的物品(标记为红色)。 我应该得到项目 1,其中的列表仅包含项目 4,而项目 4 的列表仅包含项目 11。

我正在寻找如何解决此问题的提示。

我的同事建议我从找到的项目(第 11 项)开始迭代,并使用 ParentId 转到树的开头并删除不必要的项目,但我不知道如何以这种方式移动。

我的第二种方法是使用递归创建项目 11 的路径并删除该路径包含的所有没有正确 ID 的项目,但我在如何实现创建路径时遇到问题。

您能给我建议并帮助解决问题吗?

c# caching tree
1个回答
0
投票

我将这个递归方法添加到

Item
类中:

public bool ContainsElseRemove(Func<Item, bool> condition)
{
    bool result = condition(this);
    foreach (Item child in Children.ToArray()) {
        if (child.ContainsElseRemove(condition)) {
            result = true;
        } else {
            Children.Remove(child);
        }
    }
    return result;
}

请注意,

ToArray()
是必需的,因为我们无法修改正在迭代的列表。

为了测试目的,也这个:

public void Print(int level = 0)
{
    Console.WriteLine(new String(' ', 4 * level) + ItemName);
    level++;
    foreach (Item child in Children) {
        child.Print(level);
    }
}

然后我通过向“Item 11”添加一个子项来创建此测试树,以查看它是否会被删除。

var tree = new Item {
    ItemName = "Item 1",
    Children = new List<Item> {
        new Item {
            ItemName = "Item 2",
            Children = new List<Item> {
                new Item { ItemName = "Item 5" },
                new Item { ItemName = "Item 6" },
                new Item { ItemName = "Item 7" }
            }
        },
        new Item {
            ItemName = "Item 3",
            Children = new List<Item> {
                new Item { ItemName = "Item 8" },
                new Item { ItemName = "Item 9" }
            }
        },
        new Item {
            ItemName = "Item 4",
            Children = new List<Item> {
                new Item { ItemName = "Item 10" },
                new Item {
                    ItemName = "Item 11",
                    Children = new List<Item> {
                        new Item { ItemName = "Item 14" }
                    }
                },
                new Item { ItemName = "Item 12" },
                new Item { ItemName = "Item 13" }
            }
        }
    }
};

测试:

Console.WriteLine("Before");
tree.Print();

Console.WriteLine();

Console.WriteLine("After");
tree.ContainsElseRemove(i => i.ItemName == "Item 11");
tree.Print();

打印:

Before
Item 1
    Item 2
        Item 5
        Item 6
        Item 7
    Item 3
        Item 8
        Item 9
    Item 4
        Item 10
        Item 11
            Item 14
        Item 12
        Item 13

After
Item 1
    Item 4
        Item 11

警告:“项目 1”永远不会被删除。它无法被删除,因为它是树的根,因此没有父级。但作为一种解决方法,你可以写:

if (!tree.ContainsElseRemove(i => i.ItemName == "Item 11")) {
    tree = null;
}
© www.soinside.com 2019 - 2024. All rights reserved.