【问题标题】:How to build a hierarchy with use Linq to object?如何使用 Linq 来构建层次结构?
【发布时间】:2013-07-11 11:26:34
【问题描述】:

我有一个数据结构列表:

        public List<Personal> Personals()
        {
            return new List<Personal>
                {
                    new Personal
                        {
                            Id = 0,
                            Name = "Name 0"
                        },
                    new Personal
                        {
                            Id = 1,
                            Name = "Name 1",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 2,
                            Name = "Name 2",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 3,
                            Name = "Name 3",
                            ParentId = 0
                        },
                    new Personal
                        {
                            Id = 4,
                            Name = "Name 4",
                            ParentId = 1
                        },
                    new Personal
                        {
                            Id = 5,
                            Name = "Name 5",
                            ParentId = 1
                        },
                    new Personal
                        {
                            Id = 6,
                            Name = "Name 6",
                            ParentId = 2
                        },
                    new Personal
                        {
                            Id = 7,
                            Name = "Name 7",
                            ParentId = 2
                        },
                    new Personal
                        {
                            Id = 8,
                            Name = "Name 8",
                            ParentId = 4
                        },
                    new Personal
                        {
                            Id = 9,
                            Name = "Name 9",
                            ParentId = 4
                        },
                };
        }

我想建一棵树:

public List<Tree> Trees()
            {
                return new List<Tree>
                    {
                        new Tree
                            {
                                Id = 0,
                                Name = "Name 0",
                                List = new List<Tree>
                                    {
                                        new Tree
                                            {
                                                Id = 1,
                                                Name = "Name 1",
                                                List = new List<Tree>
                                                    {
                                                        new Tree
                                                            {
                                                                Id = 4,
                                                                Name = "Name 4"
                                                            },
                                                        new Tree
                                                            {
                                                                Id = 5,
                                                                Name = "Name 5"
                                                            }
                                                    }
                                            }
                                    }
                            }
                    };
            }

你如何用 LinQ 构建一棵树来反对?我必须使用,但它不能完全正常工作,见下文:

public List<Tree> GetTree(List<Personal> list)
        {
            var listFormat = list.Select(x => new Tree
                {
                    Id = x.Id,
                    Name = x.Name,
                    ParentId = x.ParentId
                }).ToList();

            var lookup = listFormat.ToLookup(f => f.ParentId);
            foreach (var tree in listFormat)
            {
                tree.List = lookup[tree.Id].ToList();
            }

            return listFormat;
        }

【问题讨论】:

  • 如果您可以使用通用类型构建树,请分享您的示例。谢谢!

标签: c# linq tree


【解决方案1】:

你应该使用递归:

public void SomeMethod() {
     // here you get your `list`
     var tree = GetTree(list, 0);
}

public List<Tree> GetTree(List<Personal> list, int parent) {
    return list.Where(x => x.ParentId == parent).Select(x => new Tree {
        Id = x.Id,
        Name = x.Name,
        List = GetTree(list, x.Id)
   }).ToList();
}

【讨论】:

  • 感谢您的回答!但是当我应用您的代码时,它会引发异常“System.StackOverflowException”。你可以再检查一遍。
  • 如果您在list 中有任何带有循环链接的项目,就会发生这种情况。例如:{ { Id = 1, ParentId = 2 }, { Id = 2, ParentId = 1 }
  • 在下面添加了一个调整来处理有人拥有 ParentId = Id 的根节点的情况
【解决方案2】:

与上面相同,仅此代码检查您的根节点的 ParentID 与其自己的 ID 匹配的情况。

    public void SomeMethod()
    {
        // here you get your `list`
        var tree = GetTree(list, 0);
    }

    public List<Tree> GetTree(List<Personal> list, int parent)
    {
        return list.Where(x => x.ParentId == parent).Select(x => new Tree
        {
            Id = x.Id,
            Name = x.Name,
            List = x.ParentId != x.Id ? GetTree(list, x.Id) : new List<Tree>()
        }).ToList();
    }

【讨论】:

  • 这只会检测 2 个节点作为父节点直接相互引用的情况(#1 -> #2 -> #1 -> 等)。如果您引入第三个节点(#1 -> #2 -> #3 -> #1 -> 等),循环将再次抬头。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多