首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤嵌套列表并将其输出为树

过滤嵌套列表并将其输出为树
EN

Stack Overflow用户
提问于 2015-09-15 06:14:05
回答 1查看 78关注 0票数 1

我有一堂课如下

代码语言:javascript
复制
public class Material
{
  public string `MaterialName` { get; set; }
  public List<Material> `ChildMaterial` { get; set; }

}

我使用上面的类创建了一个嵌套列表,如下例所示

  • 材料A
  • 材料B
  • 材料C
    • 材料D

  • 材料J
代码语言:javascript
复制
- **Material D** 
    - Material F

  • 材料2

我想要一个linq查询的一些方法,将过滤掉材料D,并将给我的路径,直到根,并将删除它下面的所有节点。如下面的例子所示,这个材料D可以在树中的任何级别上找到,并且可以重复。

  • 材料A
  • 材料B
  • 材料C
  • 材料D
  • 材料J
  • 材料D
EN

回答 1

Stack Overflow用户

发布于 2015-09-15 08:57:19

首先,您需要一个LINQ方法,它能够将这样的树结构夷为平地,以便能够迭代所有可用的节点:

代码语言:javascript
复制
public static IEnumerable<TSource> Map<TSource>(
  this IEnumerable<TSource> source,
  Func<TSource, bool> selectorFunction,
  Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (selectorFunction == null)
        throw new ArgumentNullException("selectorFunction");

    if (getChildrenFunction == null)
        throw new ArgumentNullException("getChildrenFunction");

    return MapImpl(source, selectorFunction, getChildrenFunction);
}

private static IEnumerable<TSource> MapImpl<TSource>(
  IEnumerable<TSource> source,
  Func<TSource, bool> selectorFunction,
  Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
    // Go through the input enumerable looking for children,
    // and add those if we have them
    foreach (TSource element in source)
    {
        foreach (var childElement in MapImpl(getChildrenFunction(element), selectorFunction, getChildrenFunction))
        {
            yield return childElement;
        }

        if (selectorFunction(element))
            yield return element;
    }
}

这样,您现在就可以在主列表中运行,并找到所有想要的节点:

代码语言:javascript
复制
var matchingMaterials = MyMaterials.Map(material => true, material => material, material => material.ChildMeterials)
                                   .Where(material => material.Name = "Material D")
                                   // Materialization is needed, cause manipulation is desired while iterating over the result.
                                   .ToList();

然后您喜欢以某种方式操作这些节点(例如,从匹配的节点中删除所有子节点):

代码语言:javascript
复制
foreach(var material in matchingMaterials)
{
    material.ChildMaterials.Clear();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32578907

复制
相关文章

相似问题

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