我有一个列表(.NET),需要构建一个缩进的树结构。列表中的每个项目都有一个指示缩进级别的 Position 属性。最终结构应如下所示:
// (1) 1
// (2) 1-1
// (2) 1-2
// (2) 1-3
// (1) 2
// (2) 2-1
// (3) 2-1-1
// (1) 3
括号内的数字是 Position 属性。给定级别的每个后续项目都应该有一个标签,表明它在该级别的项目列表中的计数。如示例所示,较低的职位级别将具有某种大纲格式标签。请记住,我必须正确生成这些标签。
老实说,我已经有一段时间没有做过递归工作了,虽然我认为这将是最好的解决方案,但我只是坚持如何完成工作。我可能过于复杂了。我的想法是,当我到达“叶子”时,我应该从列表中删除该项目并返回,但我不确定。只是稍微转动一下我的轮子。
谢谢,杰
更新:
这是接近的东西,但我无法弄清楚最后一个案例。到目前为止,如果下一个项目落在同一级别或缩进一个级别,它会很好,但我需要一个案例来说明列表中的下一个项目位于小于当前位置的位置(即缩进更远左边)。另外,我不确定方法顶部的基本情况:
var sb = new StringBuilder();
BuildTree(sb, list, 0, 1, string.Empty);
return sb.ToString();
private void BuildTree(StringBuilder sb, List<Item> list, int currIndex, int count, string parentId)
{
if (list.Count == currIndex)
{
return;
}
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
}
更新:
另一种实现,但对于缩进较少的行仍然失败:
private void BuildTree(StringBuilder sb, List<Item> list, int currIndex, int count, string parentId)
{
if (list.Count == 0)
{
return;
}
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
list.RemoveAt(currIndex);
}
更新:
这是一个黑客,但它有效。我基本上是在根目录下构建多个子树。我更喜欢适当的解决方案而不是 hack,但这是我迄今为止最好的尝试。欢迎替代品:
var sb = new StringBuilder();
List<Person> list = GetTheList();
int cnt = 0;
while (list.Count > 0)
{
BuildTree(sb, list, 0, ++cnt, string.Empty);
}
return sb.ToString();
private void BuildTree(StringBuilder sb, List<Person> list, int currIndex, int count, string parentId)
{
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list.Count > 1)
{
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
}
list.RemoveAt(currIndex);
}