在自引用(父子)层次树中查找所有后代

corix010

这类似于问题(在树层次结构中为给定的子级LINQ(lambda表达式)查找父级)。但是,除了找到所有祖先之外,我还需要找到所有后代。

我正在修改Yacoub的方法,但只设法将所有后代都放在一个分支中。

    private IEnumerable<UserRole> FindAllChildrenRecursively(List<UserRole> allRoles, UserRole role)
{
    var child = allRoles.FirstOrDefault(x => x.ParentId == role.Id);

    if (child == null)
        return Enumerable.Empty<UserRole>();

    return new[] { child }.Concat(FindAllChildrenRecursively(allRoles, child));
}
伊万·斯托夫(Ivan Stoev)

我正在修改Yacoub的方法,但只设法将所有后代都放在一个分支中

这是因为此行:

var child = allRoles.FirstOrDefault(x => x.ParentId == role.Id);

虽然它可能已经适用于寻找一个单一的父母,它不适合用于查找多个孩子。

但是您不需要在allRoles列表上进行递归迭代器和多次迭代您可以使用ToLookup扩展方法创建快速查找结构,然后执行迭代DFS,如下所示:

private static IEnumerable<UserRole> FindAllChildren(List<UserRole> allRoles, UserRole role)
{
    var childrenByParentId = allRoles.ToLookup(r => r.ParentId);
    var stack = new Stack<IEnumerator<UserRole>>();
    var e = childrenByParentId[role != null ? role.Id : (int?)null].GetEnumerator();
    try
    {
        while (true)
        {
            while (e.MoveNext())
            {
                yield return e.Current;
                stack.Push(e);
                e = childrenByParentId[e.Current.Id].GetEnumerator();
            }
            if (stack.Count == 0) break;
            e.Dispose();
            e = stack.Pop();
        }
    }
    finally
    {
        e.Dispose();
        while (stack.Count > 0) stack.Pop().Dispose();
    }
}

更好的方法是(遵循DRY原理)利用“如何通过LINQ展平树”中的通用树帮助器方法

public static class TreeUtils
{
    public static IEnumerable<T> Expand<T>(
            this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
    {
        var stack = new Stack<IEnumerator<T>>();
        var e = source.GetEnumerator();
        try
        {
            while (true)
            {
                while (e.MoveNext())
                {
                    var item = e.Current;
                    yield return item;
                    var elements = elementSelector(item);
                    if (elements == null) continue;
                    stack.Push(e);
                    e = elements.GetEnumerator();
                }
                if (stack.Count == 0) break;
                e.Dispose();
                e = stack.Pop();
            }
        }
        finally
        {
            e.Dispose();
            while (stack.Count != 0) stack.Pop().Dispose();
        }
    }
}

像这样:

private static IEnumerable<UserRole> FindAllChildren(List<UserRole> allRoles, UserRole role)
{
    var childrenByParentId = allRoles.ToLookup(r => r.ParentId);
    return childrenByParentId[role != null ? role.Id : (int?)null].Expand(r => childrenByParentId[r.Id]);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从自引用的mysql表中检索父子层次结构

来自分类Dev

从自引用mysql表中检索父子层次结构

来自分类Dev

如何从具有父子层次的层次中获取上升和后代?

来自分类Dev

SQL层次查询:查找具有任何父子ID的完整树(Oracle)

来自分类Dev

查找父子节点及其子节点的层次树 - MySQL Query

来自分类Dev

SQL查找所有后代

来自分类Dev

查找所有以xml开头的元素中包含文本的后代

来自分类Dev

在具有附加条件的树中查找实体的后代(PostgreSQL)

来自分类Dev

在层次结构SQL中查找所有子级

来自分类Dev

在所有父级的树中任何节点的mysql中获取完整的父子关系树

来自分类Dev

jQuery-查找任何级别的所有后代,但找不到这些后代的后代

来自分类Dev

ngOnChanges仅击中树的根,而不是所有后代

来自分类Dev

在目录树中查找所有绝对链接

来自分类Dev

带有父子条件的自引用 MySql 表

来自分类Dev

Git-查找所有未合并的后代分支

来自分类Dev

Dojo查询以类名查找所有后代

来自分类Dev

从树或列表层次结构中查找对象

来自分类Dev

MongoDB树模型:获取所有祖先,获取所有后代

来自分类Dev

在XML中查找后代

来自分类Dev

在Visual Studio中查找对重写方法的所有引用

来自分类Dev

在表中查找引用特定列的所有存储过程

来自分类Dev

在Visual Studio中查找对重写方法的所有引用

来自分类Dev

在父子层次结构中查找最多7个级别的细分

来自分类Dev

如何基于父子关系获取项目内所有嵌套项目(层次结构)的列表?

来自分类Dev

在实体框架中创建自引用层次结构表

来自分类Dev

使用Servicestack ORMLite加载所有层次结构引用

来自分类Dev

使用Servicestack ORMLite加载所有层次结构引用

来自分类Dev

在有根的,标记的,定向树中查找所有子树重复

来自分类Dev

NSManagedObject CoreData中的父子层次结构

Related 相关文章

  1. 1

    从自引用的mysql表中检索父子层次结构

  2. 2

    从自引用mysql表中检索父子层次结构

  3. 3

    如何从具有父子层次的层次中获取上升和后代?

  4. 4

    SQL层次查询:查找具有任何父子ID的完整树(Oracle)

  5. 5

    查找父子节点及其子节点的层次树 - MySQL Query

  6. 6

    SQL查找所有后代

  7. 7

    查找所有以xml开头的元素中包含文本的后代

  8. 8

    在具有附加条件的树中查找实体的后代(PostgreSQL)

  9. 9

    在层次结构SQL中查找所有子级

  10. 10

    在所有父级的树中任何节点的mysql中获取完整的父子关系树

  11. 11

    jQuery-查找任何级别的所有后代,但找不到这些后代的后代

  12. 12

    ngOnChanges仅击中树的根,而不是所有后代

  13. 13

    在目录树中查找所有绝对链接

  14. 14

    带有父子条件的自引用 MySql 表

  15. 15

    Git-查找所有未合并的后代分支

  16. 16

    Dojo查询以类名查找所有后代

  17. 17

    从树或列表层次结构中查找对象

  18. 18

    MongoDB树模型:获取所有祖先,获取所有后代

  19. 19

    在XML中查找后代

  20. 20

    在Visual Studio中查找对重写方法的所有引用

  21. 21

    在表中查找引用特定列的所有存储过程

  22. 22

    在Visual Studio中查找对重写方法的所有引用

  23. 23

    在父子层次结构中查找最多7个级别的细分

  24. 24

    如何基于父子关系获取项目内所有嵌套项目(层次结构)的列表?

  25. 25

    在实体框架中创建自引用层次结构表

  26. 26

    使用Servicestack ORMLite加载所有层次结构引用

  27. 27

    使用Servicestack ORMLite加载所有层次结构引用

  28. 28

    在有根的,标记的,定向树中查找所有子树重复

  29. 29

    NSManagedObject CoreData中的父子层次结构

热门标签

归档