如何过滤树形结构?

时间:2013-03-06 17:52:49

标签: c# tree

我有一个对象树MyNode

public class MyNode
{
   public int Type { get; set; }
   public List<MyNode> Children { get; set; }
}

MyNode myRootNode;
// initializing a tree structure

所以我需要删除除

之外的所有节点
  1. Type属性的节点等于int myType

  2. Type属性的任何级别节点的子节点中包含的节点等于int myType

  3. 我的方式:

    bool Filter(MyNode node, MyNode parentNode, int type)
    {
       bool isFound = false;
    
       if (node.Type == type)
          isFound = true; // There's type
    
       foreach (MyNode child in node.Children)
       {
          if (FilterTree(child, node, type))
              isFound = true; // There is child node who has this type
       }
    
       // If there aren't this type neither any of its children has it
       if (!isFound)
       {
          parentNode.Children.Remove(node);
       }
    
       return isFound;
    }
    

    我有一个例外:Collection was modified; enumeration operation may not execute.我认为那是因为我删除了列表中的元素。有没有办法以正确的方式做到这一点?或者我错了什么?

2 个答案:

答案 0 :(得分:4)

假设始终保留根节点,您可以删除mathod中的子节点,而不是节点本身。

bool Filter(MyNode node,int type)
{
//remove children
foreach(MyNode child in node.Children.Where(c=>!Filter(c, type)).ToArray())
    node.Children.Remove(child);
//return if should be retained
return node.Type==type || node.Children.Count>0;
}

答案 1 :(得分:-1)

Linq来救你:

public static void RemoveNodesRecursive(this MyNode node, Predicate<MyNode> predicate)
{
    node.Children.RemoveAll(predicate);
    foreach (var n in node.Children)
    {
        RemoveNodes(n);
    }
}

然后从根节点开始:

myRootNode.RemoveNodesRecursive(n => n.node.Type == myType)