c# - 查找所有祖先直到节点 id

标签 c# lambda ienumerable

我有一个节点树,我喜欢迭代查找所有祖先,直到树中的给定点(节点)。 这样我就可以将其插入/保存回我的数据库。 到目前为止,我有如下内容,已被证明非常有用:

public IEnumerable<INode> Ancestors()
{
   var parent = this.Parent;
   while (parent != null)
   {
      yield return parent;
      parent = parent.Parent;
   }
}

我认为,我应该传递一个 Func 或 Func 来停止/中断序列。

最好的实现是什么?.Ta

编辑:给出以下答案。我正在考虑寻求更高性能的东西,例如:

 public IEnumerable<INode> Ancestors(Func<INode, bool> predicate)
 {
    var parent = this.Parent;
    while (parent != null)
    {
      if (predicate(parent))
      { 
         yield return parent;
      }
      else
      { 
         yield break; 
      }

      parent = parent.Parent;
    }
 }

我说乔恩的答案将创建 2 个枚举器,对吗?

最佳答案

怎么样:

var desiredNode = child.Ancestors().FirstOrDefault(node => node.Id == desiredId);

如果找不到正确的节点,则给出null

编辑:好的,如果您需要从下到上的完整序列,您可以使用:

var nodes = child.Ancestors().TakeUntil(node => node.Id == desiredId);

其中 TakeUntil 是类似于 TakeWhile 的方法,但它包含与谓词匹配的最终节点。您可以找到sample implementationMoreLINQ 。如果您不介意缺少参数验证(MoreLINQ 提供),那么编写起来非常简单:

public static IEnumerable<T> TakeUntil<T>(this IEnumerable<T> source,
                                          Func<T, bool> predicate)
{
    foreach (T item in source)
    {
        yield return item;
        if (predicate(item))
        {
            yield break;
        }
    }
}

可以将功能构建到Ancestors()方法中,但它将两个职责混合到一个相对复杂的函数中,而不是具有两个简单的函数,这两个函数可以以非常通用的方式与其他简单函数组合。

关于c# - 查找所有祖先直到节点 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7677187/

相关文章:

c# - 隐藏基类或接口(interface)以免污染代码

c# - 从 XmlDocument 的 NodeList 中获取属性?

c# - 如何在 C# 中将日期格式转换为 DD-MM-YYYY

java - 寻找Java8中的内置函数来忽略异常

c# - 对 BiDirection 字典使用集合初始值设定项

c# - 如何交叉多个IEnumerable?

c# - 两个列表之间的 "Left XOR"LINQ

c# - 如何确定异步套接字服务器中的流结束

c# - Lambda 表达式、捕获的变量和线程

c++ - std::function 作为自定义流操纵器