【发布时间】:2011-05-10 07:55:45
【问题描述】:
我有一个分层的对象列表。假设结构如下:
- 根节点
- 父节点
- 子节点
- 父节点
- 子节点
- 父节点
- 子节点
- 父节点
子节点可以有自己的子节点,但目标基本上是搜索“父节点”。因此,假设父节点类有一个名为“名称”的属性 - 并且用户输入了部分名称,我希望返回名称中包含用户搜索条件的所有父节点。基本上,这更像是一种“过滤器”功能。所以,我知道如何做到这一点,但是,我遇到的问题是他们的关键目标是保持层次结构的完整。换句话说,如果有一个父节点匹配过滤条件,我希望返回下面的结构:
- 根节点
- 父节点
- 子节点
- 父节点
我目前的努力只收获:
- 父节点
- 子节点
我正在使用 Linq。任何建议将不胜感激。
谢谢!
克里斯
下面的代码 sn-p 用于当前的过滤器实现:
FilteredReports = Reports.FirstOrDefault().Children.Cast<IHierarchicalResult>()
.SelectRecursive(item => item.Children.Cast<IHierarchicalResult>())
.Where(item => item.Name.ToLower().StartsWith(filterCriteria))
.ToObservableCollection();
这是我正在使用的扩展方法:
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;
}
}
}
}
【问题讨论】:
-
您能提供更多信息吗?您的分层列表属于哪种类型的集合?子节点是封装在父节点内,还是以树型结构与父节点相关?代码 sn-ps 不错!
-
集合是一个 ObservableCollection。每个节点都有一个名为 Children 的属性 - 它是同一类的 IEnumerable 集合。所以为了保持这个要求简单,使用扩展方法或其他一些干净的方法,我可以过滤根节点的初始子节点,并且仍然保持根节点完好吗?
-
我认为我需要有两个系列。一个集合是对象的原始集合,第二个集合是我的动态集合,代表过滤后的结果。我也不想假设我总是只有一个根节点。