递归搜索分层列表

Chr*_*ris 2 c# linq lambda

我有一个分层的对象列表.假设结构如下:

  • 根节点
    • 父节点
      • 子节点
    • 父节点
      • 子节点
    • 父节点
      • 子节点

子节点可以有自己的子节点,但目标是基本搜索"父节点".因此,假设父节点类具有名为"Name"的属性 - 并且用户输入部分名称,我希望返回其名称包含用户搜索条件的所有父节点.基本上,这比任何东西都更像是一个"过滤器"功能.所以,我知道如何做到这一点,然而,我遇到的问题是他们的关键目标是保持层次结构的机智.换句话说,如果有一个父节点与筛选条件匹配,我希望返回以下结构:

  • 根节点
    • 父节点
      • 子节点

我目前的努力只会产生:

  • 父节点
    • 子节点

我正在使用Linq.任何建议将不胜感激.

谢谢!

克里斯

下面的代码片段用于当前过滤器实现:

FilteredReports = Reports.FirstOrDefault().Children.Cast<IHierarchicalResult>()
                                    .SelectRecursive(item => item.Children.Cast<IHierarchicalResult>())
                                    .Where(item => item.Name.ToLower().StartsWith(filterCriteria))
                                    .ToObservableCollection();
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的扩展方法:

public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getChildren)
    {
        if (null == source)
        {
            throw new ArgumentNullException("source");
        }

        if (null == getChildren) return source;

        return SelectRecursiveIterator(source, getChildren);
    }

    private static IEnumerable<T> SelectRecursiveIterator<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> getChildren)
    {
        foreach (T item in source)
        {
            yield return item;

            IEnumerable<T> children = getChildren(item);
            if (null != children)
            {
                foreach (T child in SelectRecursiveIterator(children, getChildren))
                {
                    yield return child;
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Ian*_*cer 5

由于您要返回的Root节点与原始根节点(它具有较少子节点)不同,因此您需要创建仅包含匹配子节点的新根节点.

就像是

  Node oldRootNode = ...
  List<Node> filteredChildren = oldRootNode.Children.Where(...).ToList();
  Node newRootNode = new Node {Name = oldRootNode.Name, Children = filteredChildren};

  return newRootNode;
Run Code Online (Sandbox Code Playgroud)