【问题标题】:Convert list of items to list of tree nodes that have children将项目列表转换为具有子节点的树节点列表
【发布时间】:2016-02-01 23:58:07
【问题描述】:

我有以下课程

 public class Item 
{   
    public int Id { get; set; }           
    public int? ParentId { get; set; }
    public string Text { get; set; }
}

还有下面的树视图类

public class TreeViewModel
{
    public TreeViewModel()
    {
        this.Children = new List<TreeViewModel>();
    }

    public int Id { get; set; }
    public int NodeId { get; set; }
    public string Text { get; set; }
    public bool Expanded { get; set; }
    public bool Checked { get; set; }

    public bool HasChildren
    {
        get { return Children.Any(); }
    }

    public IList<TreeViewModel> Children { get; private set; }
}

我将收到项目列表并将其转换为树。

没有父ID的项目将成为主节点。

例子:如果我有以下物品

item[0] = Id:0 Text:User ParentId:3

item[1] = Id:1 Text:Role ParentId:3

item[2] = Id:2 Text:SubUser ParentId:0

item[3] = Id:3 Text:Admin ParentId:null

item[4] = Id:4 Text:SuperAdmin ParentId:null

item[5] = Id:5 Text:Doha ParentId:4

以下项目将列出树

我试图用递归函数来做到这一点,但我没有结果

【问题讨论】:

  • 请展示你的递归函数

标签: c# tree


【解决方案1】:

您不需要递归函数来执行此操作:

var models = items.Select(i => new TreeViewModel
{
    Id = i.Id,
    ...
}).ToList();

foreach (var model in models){
    model.Children.AddRange(models.Where(m => m.ParentId == model.Id));
}

如果你想得到你的树的根,你可以使用:

var roots = models.Where(m => !m.ParentId.HasValue);

【讨论】:

  • @Mr.White 那些相关的项目将是同一棵树的一部分。
  • 完全错过了检查 ParentId 的第二部分:/
  • 这是一个 O(n^2) 算法,可以简单地作为 O(n) 算法完成,因此随着节点数量的增加,扩展性会很差。
  • @Mr.White 这不是真的。
【解决方案2】:

这是一种快速的 O(N) 时间复杂度方法:

List<Item> list = ...;
// Pre create all nodes and build map by Id for fast lookup
var nodeById = list
    .Select(item => new TreeViewModel { Id = item.Id, Text = item.Text })
    .ToDictionary(item => item.Id);
// Build hierarchy
var tree = new List<TreeViewModel>();
foreach (var item in list)
{
    var nodeList = item.ParentId == null ? tree, nodeById[item.ParentId.Value].Children;
    nodeList.Add(nodeById[item.Id]);
}

【讨论】:

  • 谢谢,它适用于我:),但现在我生成树后我想删除一些节点,例如 id = 0 且没有子节点的节点,我尝试很多,一无所获 ,, tree.RemoveAll(x.id==0 && x.hasChildern==false) ,,, 我如何从所有孩子的树中删除??????
  • @Doha 欢迎您。删除问题怎么样,请发布一个新问题,我们很乐意为您提供帮助。
  • @Doha 看起来社区不喜欢这个新问题。据我了解,您想从结果中删除一些节点。由于tree 列表包含 root 节点,因此每个节点都包含 Children 列表,您可以创建一个递归方法来满足您的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2022-12-21
相关资源
最近更新 更多