多层父子级别排序

4

我有一个项目列表

  • ID 名称 父ID
  • 1 abc 0 (第一级)
  • 2 def 1
  • 3 ghi 1
  • 4 jkl 0
  • 5 mno 2
  • 6 pqr 5
  • 7 aaa 1
  • 8 vwx 0

我希望将该列表按以下方式排序:

abc, aaa, def, mno, ghi, jkl, vwx,

即,我希望父级按名称升序排列,其子级(按名称升序排列),子级的子级(按子级升序排列)等等,直到最后一级,然后重复以上操作。

sections = new List<section>( from section in sections
                     group section by section.ParentID into children
                     orderby children.Key
                     from childSection in children.OrderBy(child => child.Name)
                     select childSection);

但是将列表排序为abc,jkl,vwx,aaa,def,ghi,mno,pqr。

有人能告诉我哪里错了吗?


在 List<section> 填充数据之后,你可以直接调用 sections.Sort。否则,创建一个 SortedList 作为 sections。 - MethodMan
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
谢谢,我以后不会再这样做了。 - Sneha S Murthy
这是一个递归问题,几天前有一个类似的问题被问到,而且有一个有趣的答案是这个 - Wasp
2个回答

5

这里提供了一个使用栈的完整解决方案。虽然这个算法可以得到改进,但是它是通用的。

public class Section
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int ParentID { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var sections = new List<Section>
            {
                new Section { ID = 1, Name = "abc", ParentID = 0 },
                new Section { ID = 2, Name = "def", ParentID = 1 },
                new Section { ID = 3, Name = "ghi", ParentID = 1 },
                new Section { ID = 4, Name = "jkl", ParentID = 0 },
                new Section { ID = 5, Name = "mno", ParentID = 2 },
                new Section { ID = 6, Name = "pqr", ParentID = 5 },
                new Section { ID = 7, Name = "aaa", ParentID = 1 },
                new Section { ID = 8, Name = "vwx", ParentID = 0 }
            };

        sections = sections.OrderBy(x => x.ParentID).ThenBy(x => x.Name).ToList();
        var stack = new Stack<Section>();

        // Grab all the items without parents
        foreach (var section in sections.Where(x => x.ParentID == default(int)).Reverse())
        {
            stack.Push(section);
            sections.RemoveAt(0);   
        }

        var output = new List<Section>();
        while (stack.Any())
        {
            var currentSection = stack.Pop();

            var children = sections.Where(x => x.ParentID == currentSection.ID).Reverse();

            foreach (var section in children)
            {
                stack.Push(section);
                sections.Remove(section);
            }
            output.Add(currentSection);
        }
        sections = output;
    }

没有所谓的“level”字段……我只是标记了一下根目录。对于造成的困惑,我感到抱歉。 - Sneha S Murthy
糟糕,应该是ParentID - John Kalberer
这给我带来了与之前相同的结果。 - Sneha S Murthy
请告诉我我哪里出错了。 - Sneha S Murthy
我已经更新了我的答案并提供了解决方案。我相信这段代码可以改进。 - John Kalberer
显示剩余2条评论

0
首先按照子项名称排序,然后按父项ID分组排序,因为否则根据您现在拥有的内容,您得到的输出是绝对正确的,因为一旦记录被分组,它们仅在分组内排序。

请您详细解释一下。请在代码中指出我错过了哪里。 - Sneha S Murthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接