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 的项目,但我在如何实现创建路径时遇到问题。
您能给我建议并帮助解决问题吗?
我将这个递归方法添加到
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;
}