2013-03-06 193 views
1

我有对象的MyNode树:如何过滤树结构?

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

MyNode myRootNode; 
// initializing a tree structure 

所以我需要删除除了具有Type财产

  1. 节点的所有节点等于包含int myType

  2. 节点他们的子节点在Type属性的任何级别节点上等于int myType

我的方式:

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

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

+0

你确实需要修改的只是过滤初始集合(选择满足条件的项目)? – Dima 2013-03-06 18:06:23

回答

4

假设根节点始终保留,您可以在马托取出孩子,而不是节点本身。

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

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