我找不到或想出一个通用且优雅的算法来让我填充树状结构。最简单的例子是博客存档:我有一堆可以按日期选择和排序的记录。我想要一棵树,其中年份可能是最高级别,几个月是下一个级别,而实际的帖子标题又是下一个。
到目前为止,我已经想出了一个可行的简单直接实现,但我确信可以使用 LINQ 等进行改进。这里我只是按日期对记录进行排序并反复检查年份或月份是否发生了变化,然后添加相应的树节点。“BlogEntry”是一个类,它同时引用了父级和子级,后来用于生成 HTML。
我欢迎有关改进算法的建议!
IEnumerable<Post> posts = db.Posts.OrderBy(p => p.DateCreated);
var topPost = posts.First();
int curYear = topPost.DateCreated.Year;
int curMonth = topPost.DateCreated.Month;
//create first "year-level" item
var topYear = new BlogEntry { Name = topPost.DateCreated.Year.ToString().ToLink(string.Empty) };
entries.Add(topYear);
var currentYear = topYear;
var topMonth = new BlogEntry { Name = topPost.DateCreated.ToString("MMMM").ToLink(string.Empty), Parent = currentYear };
currentYear.Children.Add(topMonth);
var currentMonth = topMonth;
foreach (var post in posts)
{
if(post.DateCreated.Year == curYear)
{
if (post.DateCreated.Month != curMonth)
{
//create "month-level" item
var month = new BlogEntry { Name = post.DateCreated.ToString("MMMM").ToLink(string.Empty), Parent = currentYear };
currentYear.Children.Add(month);
currentMonth = month;
curMonth = post.DateCreated.Month;
}
//create "blog entry level" item
var blogEntry = new BlogEntry { Name = post.Title.ToLink("/Post/" + post.PostID + "/" + post.Title.ToSeoUrl() ), Parent = currentMonth };
currentMonth.Children.Add(blogEntry);
}
else
{
//create "year-level" item
var year = new BlogEntry { Name = post.DateCreated.Year.ToString().ToLink(string.Empty) };
entries.Add(year);
currentYear = year;
curMonth = post.DateCreated.Month;
curYear = post.DateCreated.Year;
}
}