【问题标题】:Delete item in nested collections of Nth level删除第 N 级嵌套集合中的项目
【发布时间】:2015-06-07 12:26:31
【问题描述】:

我在尝试删除树结构对象中的项目时遇到问题。

我的对象如下

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)
            }
        }
    }

有没有其他方法可以打破递归。

【问题讨论】:

  • 你提前知道节点在树中只会出现一次吗?
  • 你能发布你实际的、准确的代码吗?您在此处发布的内容甚至无法编译。
  • 我想我看到有人发布了答案,但删除了无法在 foreach 循环中操作集合。我希望这个人没有删除他的评论,所以我可以给他信用。 . .

标签: c# recursion


【解决方案1】:

我会通过对我的设计做一些小改动来解决这个问题(假设你问题中的 sn-p 是一个类的伪代码):

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

    public void Delete()
    {
        Parent.Children.Remove(this);
    }
}

这为您在操作对象图时维护额外的引用提供了更多的工作,但在执行删除等操作时可以节省大量精力和代码,如上所示。

您还没有展示如何构造TreeNodes,但我会为构造函数的子参数创建父级和集合。

【讨论】:

  • 一个非常优雅的解决方案!
【解决方案2】:

只要不更改原始集合,您就可以安全地遍历子节点集合并将其删除。这可以通过创建集合的数组并对其进行迭代来完成。

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 循环不会抛出异常。那是因为原始集合发生了变化,而我们迭代了第二个集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多