我有一个分层的对象列表.假设结构如下:
子节点可以有自己的子节点,但目标是基本搜索"父节点".因此,假设父节点类具有名为"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)
由于您要返回的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)