隐藏Tree Object Recursive的节点

时间:2013-01-16 15:32:38

标签: c# algorithm data-structures recursion tree

我正在寻找一种隐藏树中节点的方法。 我正在过滤一个节点类型的节点,这是我原来的结构:

root
 +FolderA
    -File1
    -File2
    -File3
 +FolderB
    -File4
    -File5
    +FolderB-1
            -File6

这就是我要做的事情:

+root
 -File1
 -File2
 -File3
 -File4
 -File5
 -File6

我创建了一个包含类型和子列表的类XNode。 (这是缩写的伪语言)

Class XNode
  MyType type;
  string Name;
  List<XNode> childrens; 
End Class

我创建了一个查询我的数据库并创建原始树的工厂类。

我创建了一个Xaml treeView UserControl来绑定我创建的根XNode。

通过Xaml无法隐藏节点,此操作必须使用绑定对象(我创建的根Xnode)完成。

现在我的问题是: 有递归的alghoritms来取消“文件夹类型”节点,获取它的子节点并将它们添加到父节点?

我试试:

  public XNode RemoveFoldersElements(ref XNode rootNode)
    {

        if (rootNode != null)
        {
            if (rootNode.Children.Count > 0)
            {
                for (int i = 0; i < rootNode.Children.Count; i++)
                {
                    XNode children = rootNode.Children.ElementAt(i);
                    if (children.WType == NodeType.Type_FOLDER)
                    {
                        XNode tempNode = RemoveFoldersElements(ref children);
                        if (tempNode != null)
                            rootNode.Children.Add(tempNode);
                        rootNode.Children.RemoveAt(i);
                    }
                    else
                    {
                        RemoveFoldersElements(ref children);
                    }

                }
            }

        }
        return null;
    }

但不成功,因为并非所有Type_FOLDER节点都被删除(它跳一级)! 有什么想法吗?

1 个答案:

答案 0 :(得分:0)

好的,这就是想法,在过滤时弄平树:

public static IEnumerable<TSource> Flatten<TSource>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TSource>> childCollectionSelector, Func<TSource, bool> predicate)
{
    foreach (var item in source)
    {
        if(predicate(item))
            yield return item;
        foreach (var subitem in childCollectionSelector(item).Flatten(childCollectionSelector, predicate).Where(predicate))
        {
            yield return subitem;
        }
    }
}

你可以像这样使用它:

var rootList = new []{rootElement}; // Flattening works on the collection
var files = rootList.Flatten(x => x.children, x => x.type == MyType.FILE);

它将起作用,授予您没有任何循环引用并且所有集合都已初始化。如果你确实有循环依赖,你会向StackOverflowException ...

打个招呼
相关问题