首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归搜索分层列表

递归搜索分层列表
EN

Stack Overflow用户
提问于 2010-11-15 16:03:04
回答 3查看 1.8K关注 0票数 2

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

node

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

代码语言:javascript
复制
- Parent node 
    - child node

代码语言:javascript
复制
- Parent node 
    - child node

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

node

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

我目前的努力只会产生以下结果:

node

  • 父节点
    • 子节点

我在用林克。如有任何建议,将不胜感激。

谢谢!

克里斯

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

代码语言:javascript
复制
FilteredReports = Reports.FirstOrDefault().Children.Cast<IHierarchicalResult>()
                                    .SelectRecursive(item => item.Children.Cast<IHierarchicalResult>())
                                    .Where(item => item.Name.ToLower().StartsWith(filterCriteria))
                                    .ToObservableCollection();

下面是我使用的扩展方法:

代码语言:javascript
复制
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;
                }
            }
        }
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-11-15 16:09:51

由于您希望返回的根节点与原始根节点不一样(它有更少的子节点),所以需要创建一个新的根节点,只包含匹配的子节点。

有点像

代码语言:javascript
复制
  Node oldRootNode = ...
  List<Node> filteredChildren = oldRootNode.Children.Where(...).ToList();
  Node newRootNode = new Node {Name = oldRootNode.Name, Children = filteredChildren};

  return newRootNode;
票数 5
EN

Stack Overflow用户

发布于 2010-11-15 16:09:18

从内存(可能包含键入)和基于不知道您的代码:

代码语言:javascript
复制
var filteredList = myRootNode.CollectionOfParentNodes.Where(p => p.Name.Contains(searchCriteriaString)).ToList();
票数 0
EN

Stack Overflow用户

发布于 2010-11-15 16:09:58

这里有几件事你可以做。

  1. --您可以创建主结构的副本并从过滤器中返回它(尽可能地进行浅拷贝,但必须深入复制节点之间的链接)
  2. --您可以扩展节点以了解它们是否已被过滤(如IsFilteredOut、ChildrenUnfilteredGet()等)。然后显示“过滤”树。
  3. 可以存储一个过滤节点列表(黑名单或白名单),然后在显示树时引用该列表(这涉及代码更改最少,但处理能力最大)。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4186223

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档