1

我的任务是根据一些数据结构生成目录文件。数据如下所示:

class ToCItem
{
    public Dictionary<int, string> path;
    public int page;
}

对于这样的示例数据:

ToCItem
{
    path = { 1 => "chapter 1" },
    page = 1;
}

ToCItem
{
    path = { 1 => "chapter 1", 2 => "section 1" },
    page = 2;
}

ToCItem
{
    path = { 1 => "chapter 1", 2 => "section 2" },
    page = 6;
}

ToCItem
{
    path = { 1 => "chapter 1", 2 => "section 2", 3 => "image" },
    page = 7;
}

ToCItem
{
    path = { 1 => "summary" },
    page = 8;
}

我需要这样的输出:

.chapter 1: 1
..section 1: 2
..section 2: 6
...image: 7
.summary: 8

(点是标签)

我想不出任何算法来做到这一点。我的第一个想法是按每个层次结构级别对项目进行分组,然后执行以下操作:

foreach (var group in paths.GroupBy(p => p.Path[1]))
            {
                if (group.Key != null)
                {
                    Console.Write("\t");
                    Console.WriteLine(group.Key);
                }
                var grouped2 = group.GroupBy(g => g.Path.ContainsKey(2) ? g.Path[2] : null);
                foreach (var group2 in grouped2)
                {
                    if (group2.Key != null)
                    {
                        {
                            Console.Write("\t\t");
                            Console.WriteLine(group2.Key);
                        }
                    }
                    var grouped3 = group.GroupBy(g => g.Path.ContainsKey(3) ? g.Path[3] : null);
                    foreach (var group3 in grouped3)
                    {
                        if (group3.Key != null)
                        {
                            Console.Write("\t\t\t");
                            Console.WriteLine(group3.Key);
                        }
                    }
                }
            }

但后来我只得到层次结构而不是实际路径。此外,这不会随着更深层次的层次而扩展。有没有人有任何想法?

4

2 回答 2

3

+1 to Rawling's answer. If you don't want to use LINQ, here's an old-fashioned method to do the same:

public string ItemToString(ToCItem item)
{
    var length = item.path.Count;

    var builder = new StringBuilder();
    builder.Append(new string('\t', length));
    builder.Append(item.path[length] + ": ");
    builder.Append(item.page);
    return builder.ToString();
}
于 2013-05-20T13:16:03.850 回答
2

尽管我很乐意为您整理一个递归解决方案,但我认为没有必要。看起来你应该能够做到

IEnumerable<string> lines = paths
    .OrderBy(toc => toc.page)
    .Select(toc =>
        /* one tab per depth */
        new string('\t', toc.path.Count) +
        /* title of item */
        toc.path.OrderByDescending(kvp => kvp.Key).Select(kvp => kvp.Value).First() +
        ": " +
        /* page number */
        toc.page);

请注意,如果您的属性只是一个(或数组)而不是字典,那么标题行会整洁!pathList<string>string

编辑:正如下面丹尼斯的回答所指出的,只要你的字典键是一致的,你就可以使用

toc.path[toc.path.Count]

获得标题,而不是像我上面所做的那样进行排序和选择。

于 2013-05-20T13:12:42.993 回答