一种对目录项进行分组的算法
本文关键字:算法 一种 | 更新日期: 2023-09-27 18:14:20
我的任务是根据一些数据结构生成一个目录文件。数据如下所示:
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);
}
}
}
}
但是我只能得到层次结构而不是实际的路径。这也不能扩展到更深的层次结构。有人有什么想法吗?
+1罗林的答案。如果你不想使用LINQ,这里有一个老式的方法来做同样的事情:
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();
}
虽然我很乐意为您提供递归解决方案,但我认为没有必要。看起来你应该可以输入
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);
请注意,如果您的path
属性只是List<string>
(或string
数组)而不是字典,那么标题行将更整洁!编辑:正如Dennis下面的回答所指出的,只要你的字典键是一致的,你可以使用
toc.path[toc.path.Count]
来获取标题,而不是像上面那样进行排序和选择。