c#层次结构列表(树)到展平列表

时间:2015-08-07 09:30:30

标签: c#

我有以下课程:

public class Item
{

    public Item()
    {
        this.Items = new List<Item>();
    }

    public string Id { get; set; }
    public string ParentId { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
    public string Content { get; set; }
    public string UserId { get; set; }
    List<Item> Children { get; set; }
}

此类将提供具有N个深层(父 - 子)的树层次结构

所以基本上当我将层次结构作为列表时:

List<Item> items = JsonConvert.DeserializeObject<List<Item>>("json in here")

结果与此类似:深度可以是X级。可以有一个或多个父母(ParentId = null是顶级)

  • 父(Id:1,ParentId:null)
    • Child(Id:1.1,ParentId:1)
      • Child(Id:1.1.1,ParentId:1.1)
    • Child(Id:1.2,ParentId:1)
      • Child(Id:1.2.1,ParentId:1.2)
      • Child(Id:1.2.2,ParentId:1.2)
    • Child(Id:1.3,ParentId:1)
  • 父(Id:2,ParentId:null)
    • Child(Id:2.1,ParentId:2)
      • Child(Id:2.1.1,ParentId:2.1)
    • Child(Id:2.2,ParentId:2)
      • Child(Id:2.2.1,ParentId:2.2)
      • Child(Id:2.2.2,ParentId:2.2)
    • Child(Id:2.3,ParentId:2)
  • 父(Id:3,ParentId:null)

现在,我需要将此层次结构保存到数据库表中。

我的问题如何将此层次结构展平为List<Item>

编辑:

IdParentId是Guids。

4 个答案:

答案 0 :(得分:0)

您可以向Item类添加一个函数,如下所示:

public IEnumerable<Item> GetItems()
{
    var result = Children.SelectMany(i => i.GetItems()).ToList();

    result.Add(this);

    return result;
}

然后叫它

var allItems = myRootItem.GetItems();

答案 1 :(得分:0)

以下是几个选择:

public IEnumerable<Item> GetItems()
{
    return
        new [] { this }
            .Concat(this.Children.SelectMany(i => i.GetItems()));
}

public IEnumerable<Item> GetItems()
{
    yield return this;
    foreach (var descendent in this.Children.SelectMany(i => i.GetItems()))
    {
        yield return descendent;
    }
}

答案 2 :(得分:0)

此递归函数可能有助于将数据保存在平面结构中:

class Test
{
    List<Item> Items = new List<Item>();
    List<Item> GetList()
    {
        return getList_Rec(this.Items);
    }

    private List<Item> getList_Rec(List<Item> items)
    {
        var result = new List<Item>();
        result.AddRange(items);
        items.ForEach(x => result.AddRange(x.Children));
        return result;
    }
}

答案 3 :(得分:-1)

如果你暴露儿童,所以它不是私人的,你可以这样做:

public IEnumerable<Item> GetItems(IEnumerable<Item> items)
{
    foreach(var item in items)
    {
        yield return item;
        foreach(var child in GetItems(item.Children))
        {
            yield return child;
        }
     }
 }

然后输入您的父母列举并获得一个单一的列表。