使用列表内的列表打印对象列表

时间:2016-07-05 20:00:29

标签: c# list

我正在尝试使用子项打印此列表,所有子项都用数字分隔,例如:

1 item 1
2 item 2
2.1 Item 2 sub 1
2.2 item 2 sub 2
2.2.1 item 2 sub 2 sub 1
3 last

那是:

  1. 项目编号从1开始。
  2. 项目应在显示其项目编号之前打印一个“行标题”。
  3. 当列表中的项目本身是一个列表时,使用前一项目的行标题打印其元素,并附加当前列表的每个元素的项目编号。即标题看起来像#.#...#.X,其中#.#...#表示此规则构造的前一项的行标题,X是当前列表中当前元素的项目编号。
  4. 如果列表显示为列表中的第一项,这样就没有“前面的项目”,则假定前面的项目是为了生成“上一项的行标题”,即行标题将包括索引值1,即使之前没有该索引的项目。
  5. 我几乎使用了这段代码:

     var input = new List<object>
            {
                 "item 1",
                 "item 2",
                 "item 3",
                 new List<object>{
                     "level 2, item 1",
                     "level 2, item 2",
                     new List<object>{
                         "level 3, item 1",
                          new List<object>{
                             "level 4, item 1",
                             "level 4, item 2"
                          },
                         "level 3, item 2",
                     },
                     "level 2, item 3",
                 },
                 "last item"
            };
    
    
    public static string Solve(List<object> list, int level = 0, int subLevel = 0)
    {
        var result = new StringBuilder();
        if (level == subLevel)
        {
            level = 0;
        }
    
        list.ForEach(x =>
        {
            var type = x.GetType();
    
            if (subLevel != 0)
            {
                result.Append(subLevel.ToString() + ".");
                Console.Write(subLevel.ToString() + ".");
            }
    
            if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(List<>)))
            {
                var newLevelList = x as List<object>;
                result.Append(Solve(newLevelList, level, level));
            }
            else
            {
                level = level + 1;
                result.AppendLine(level.ToString() + " " + x.ToString());
                Console.WriteLine(level.ToString() + " " + x.ToString());
            }
        });
    
        return result.ToString();
    }
    

    但它不适用于第4级子项目,例如:

    我收到了这个输出:

    1 item 1
    2 item 2
    3 item 3
    3.1 level 2, item 1
    3.2 level 2, item 2
    3.2.1 level 3, item 1
    2.1.1 level 4, item 1
    1.2 level 4, item 2
    2.2 level 3, item 2
    3.3 level 2, item 3
    4 last item
    

    我错过了什么?我也愿意接受新的解决方案。

1 个答案:

答案 0 :(得分:1)

如果没有更多详细信息,很难准确理解您要完成的任务。但是,基于您给出的示例,在我看来,当算法找到子列表时,您希望将当前项索引保留在行标题中,并追加从{{1}开始的新级别的索引到那个标题。即如果您刚刚显示了项目1,并且列表后面的列表,则列表中的第一项应显示为"2 item 2",而不是显示为"2.1 Item 2 sub 1"(即列表)本身并不算作该级别的新指数。)

如果我理解正确,那么这样的事情应该做你想做的事情:

"3.1 Item 2 sub 1"

请注意,我不是将索引传递给方法,而是简单地传递行的标头前缀,而不是使用显式反射来标识列表中的static string Solve(List<object> source, string prefix = "") { int itemIndex = 0; StringBuilder result = new StringBuilder(); foreach (object item in source) { List<object> listItem = item as List<object>; if (listItem != null) { result.Append(Solve(listItem, prefix + itemIndex + ".")); } else { itemIndex++; result.AppendLine(prefix + itemIndex + " " + item); } } return result.ToString(); } 元素,我只使用C#{{1} }运算符对类型进行条件转换。

<强>&LT;编辑&gt;

根据您的评论,当您希望列表项目采用前一项目的索引时,您仍然希望容纳没有前一项目的列表项目。恕我直言,这有点奇怪,但通过解决特殊情况很容易解决,如下所示:

List<object>

<强>&LT; /编辑&gt;

如果上述问题无法解决您的疑虑,请改进问题,以便更准确地描述您想要输出的具体输入。