【问题标题】:Populate a tree from a List of string arrays从字符串数组列表中填充树
【发布时间】:2013-05-11 02:26:00
【问题描述】:

我有数组列表:

List<HeaderItem> _headerItems = new List<HeaderItem>();


class HeaderItem
{
    private string[] _headers = new string[6];

    public string this[int index]
    {

        get
        {
            return _headers[index];
        }
        set
        {
            _headers[index] = value;
        }
    }
}

数组中的 6 个项目中的每一个都代表层次结构中的一个级别。如果数组位置 0 中的所有项目都匹配,则将存在单个根级别节点。

所以,

A,B,C

A,B,D

B,C,D

B,D,E

会产生:

一个

....B

........C

........D

B

....C

........D

....D

........E

等等……

目前我的解决方案已经被破解了,虽然它有效,但我正在尝试提出一种“酷”的方法。

【问题讨论】:

    标签: c# list hierarchy


    【解决方案1】:

    您可以通过递归调用 print 方法来实现这一点,为它提供要打印的项目的子集和到目前为止打印的树的深度。我修改了你的类以包含一个Length 属性,这样调用者就不必总是假设它是 6。我还添加了一个构造函数来简化我的初始化。可能在您的代码中没有意义。

    public class HeaderItem
    {
        public HeaderItem(string headers)
        {
            _headers = headers.ToCharArray().Select(x => x.ToString()).ToArray();
        }
    
        private string[] _headers = new string[6];
    
        public int Length
        {
            get { return _headers.Length; }
        }
    
        //...
    }
    

    这是打印方法。看看它是如何进行分组然后递归调用自身的:

    private static void PrintHeaders(IEnumerable<HeaderItem> headerItems, int depth = 0)
    {
        var result =
            headerItems.Where(h => h.Length > depth)
                       .GroupBy(h => h[depth], h => h,
                                  (k, g) => new {Key = k, Items = g})
                       .OrderBy(g => g.Key);
    
        foreach (var pair in result)
        {
            Console.Write(new string('.', depth)); // change here to add more dots
            Console.WriteLine(pair.Key);
            PrintHeaders(pair.Items, depth + 1);
        }
    }
    

    你可以这样称呼它:

    PrintHeaders(_headerItems);
    

    为了测试,这是我的Main 方法:

    static void Main(string[] args)
    {
        _headerItems.Add(new HeaderItem("abc"));
        _headerItems.Add(new HeaderItem("abd"));
        _headerItems.Add(new HeaderItem("acd"));
        _headerItems.Add(new HeaderItem("ace"));
        _headerItems.Add(new HeaderItem("bce"));
        _headerItems.Add(new HeaderItem("bcd"));
        _headerItems.Add(new HeaderItem("bef"));
    
        PrintHeaders(_headerItems);
    
        Console.ReadLine();
    }
    

    结果如下:

    a
    .b
    ..c
    ..d
    .c
    ..d
    ..e
    b
    .c
    ..d
    ..e
    .e
    ..f
    

    【讨论】:

      【解决方案2】:

      当创建树时,总是在该实体中创建一个实体列表,像这样

      class HeaderItem
      {
          private string[] _headers = new string[6];
      
          private List<HeaderItem> _items;
      
          public string this[int index]
          {
              get
              {
                  return _headers[index];
              }
              set
              {
                  _headers[index] = value;
              }
          }
      
          public List<HeaderItem> Items
          {
              get
              {
                  if (_items == null)
                      _items = new List<HeaderItem>();
                  return _items;
              }            
          }
      }
      

      【讨论】:

      • 我绝对明白你的意思,但是我只需要将它打印到屏幕上,这样我的解决方案就不需要对象模型来完成。非常同意您对子类化的观点。有什么关于快速加餐程序的吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      相关资源
      最近更新 更多