LINQ递归函数?

标签 linq c#-4.0 recursion

我们以这个n层深度结构为例:

public class SomeItem 
{
     public Guid ID { get;set; }
     public string Name { get; set; }
     public bool HasChildren { get;set; }
     public IEnumerable<SomeItem> Children { get; set; }
}

如果我想通过 ID(结构中的任何位置)获取特定项目,是否有一些 LINQ 优点可以用来在单个语句中轻松获取它,或者我是否必须使用一些递归函数,如下所示:

   private SomeItem GetSomeItem(IEnumerable<SomeItem> items, Guid ID)
    {
        foreach (var item in items)
        {
            if (item.ID == ID)
            {
                return item;
            }
            else if (item.HasChildren)
            {
                return GetSomeItem(item.Children, ID);
            }
        }
        return null;
    }

最佳答案

LINQ 并不能很好地“执行”递归。您的解决方案似乎很合适 - 虽然我不确定是否真的需要 HasChildren ......为什么不对没有 child 的项目使用空列表?

另一种方法是编写一个DescendantsAndSelf 方法,它将返回所有 后代(包括项目本身),像这样;

// Warning: potentially expensive!
public IEnumerable<SomeItem> DescendantsAndSelf()
{
    yield return this;
    foreach (var item in Children.SelectMany(x => x.DescendantsAndSelf()))
    {
        yield return item;
    }
}

但是,如果树很深,最终效率会非常低,因为每个项目都需要“通过”其祖先的所有迭代器。韦斯代尔有blogged about this , 显示出更有效的实现。

无论如何,如果您有这样的方法(无论它是如何实现的),您可以只使用普通的“where”子句来查找项目(或 First/FirstOrDefault 等)。

关于LINQ递归函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27992975/

相关文章:

c# - 动态对象,可持久保存到 Azure 并可通过 Dynamic Linq 进行查询

c# - 以前从未使用过 LocalDB

C#:不匹配一组单词的正则表达式

recursion - 达到基本情况后无法从 Prolog 中的递归中获取结果

c++ - g++中的尾递归问题

c# - 将 foreach 循环更改为 lambda

c# - Nhibernate Map 复合元素

c# - 添加或到 linq 查询

c# - 如何在 Visual Studio 中连接到 Sqlite 并创建数据库?

c - 具有十进制输入的递归函数以二进制形式打印从零到 n 的所有数字