删除第n级嵌套集合中的项

本文关键字:集合 嵌套 删除 | 更新日期: 2023-09-27 17:54:20

我在试图删除树结构对象中的项目时遇到麻烦。

我的对象如下

TreeNode
{
    string name;
    ObservableCollection<TreeNode> Children;
}

我想如果我递归地处理树并找到我的节点并删除它,但我遇到了麻烦。

我做了一些关于

的事情

更新:

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if(children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach(var child in children)
        {
            DeleteNode(child, nodetodelete);
        }
    }
}

我在编写代码时意识到,在迭代一个有可能被更改的集合时,我最终会遇到操作异常。
我可以建立一个巨大的for循环的变化,因为我知道最大深度长度(我做了一个占位符),但这似乎真的很糟糕. . . .
谁能给我指个大概的方向吗?我有点想知道是不是我的数据结构导致了这个问题。

更新:

这看起来很糟糕,有点代码味,但我得到了递归"工作"当我找到我的节点时抛出异常。

DeleteNode(children, nodetodelete)
    {
        if(children.remove(nodetodelete)
        {
            throw FoundException();
        }
        else
        {
            foreach(var child in children)
            {
                DeleteNode(child, nodetodelete)
            }
        }
    }

是否有其他方法可以跳出递归

删除第n级嵌套集合中的项

我会通过对我的设计做一个小的改变来处理这个问题(假设你的问题中的代码片段是一个类的伪代码):

TreeNode
{
    string name;
    TreeNode Parent;
    ObservableCollection<TreeNode> Children;
    public void Delete()
    {
        Parent.Children.Remove(this);
    }
}

这使得你在操作对象图时维护一个额外的引用多了一点工作,但是当你做像上面看到的删除这样的事情时,节省了你很多的精力和代码。

您还没有展示如何构造TreeNode s,但是我将为构造函数的子参数创建父参数和集合。

只要不更改原始集合,就可以安全地遍历子节点集合并删除它们。这可以通过创建集合的数组并遍历它来实现。

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if (children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach (var child in children.ToArray())
        {
            // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children"
            DeleteNode(child, nodetodelete);
        }
    }
}

这将创建一个新的集合供您迭代。如果从children中删除了子节点,则foreach循环不会抛出异常。这是因为当我们遍历次要集合时,更改了原始集合。