English 中文(简体)
如何使用C#迭代层级数据并输出层次结构
原标题:
  • 时间:2008-11-16 14:22:50
  •  标签:

鉴于以下类...

public class Category {
  public string Name {get;set;}
  public Category ParentCategory {get;set;}
}

从类别对象的集合(IList<Category>)中输出以下内容的最有效方法是什么?

+ Parent Category
++ Sub Category
++ Sub Category 2
+ Parent Category 2
++ Sub ...
++ Sub ..
++ Sub ....

编辑:也许真正的问题应该是,我应该如何在数据库中表示这个模型,并使用 NHibernate 检索它?

最佳回答

您可以考虑反转您的关系。如果一个节点可以到达其父节点但反之则不行,则必须拥有所有叶节点才能打印出完整的树形结构。将其与每个节点都知道其子节点的情况进行比较-那么您只需要根节点即可。

问题回答

一个小的递归函数就能为您完成它。

static void recurseCategories(ref List<Category> cl, Category start, int level)
{
  foreach (Category child in cl)
  {
    if (child.ParentCategory == start)
    {
      Console.WriteLine(new String(   , level) + child.Name);
      recurseCategories(ref cl, child, level + 1);
    }
  }
}

我的假设是:

  • You ve got an List of Category. (Of course all Category objects you want to print must be in that list. I thought that was self-evident, but seemingly it was not.)
  • The root category has a parent of null. The initial function call should therefore be recurseCategories(ref myCategoryList, null, 0).
  • No orphaned elements exist in your list. Some error handling code should be added.
  • Output order will be coherent to whatever order the list is iterated, so apart from the hierarchy it s more or less coincidental.

最近我了解了层次化Linq查询,查看http://weblogs.asp.net/okloeten/archive/2006/07/09/Hierarchical-Linq-Queries.aspx

但我倾向于同意Jon Skeet的观点。

@Tomalok,当我使用这个数据结构运行你的代码时,我得到了两个节点。

class Program
{
    static void Main(string[] args)
    {
        var foo = new List<Category>();

        // Example structure from Question
        var fail1 = new Category() { Name = "test1" };
        var fail2 = new Category() { Name = "test2", ParentCategory = fail1 };
        var fail3 = new Category() { Name = "test3", ParentCategory = fail1 };
        var fail4 = new Category() { Name = "test4"};
        var fail5 = new Category() { Name = "test5", ParentCategory = fail4 };
        var fail6 = new Category() { Name = "test6", ParentCategory = fail4 };
        var fail7 = new Category() { Name = "test7", ParentCategory = fail4 };

        foo.Add(fail1);
        foo.Add(fail4);

        recurseCategories(ref foo, null, 0);

    }

    static void recurseCategories(ref List<Category> cl, Category start, int level)
    {
        foreach (Category child in cl)
        {
            if (child.ParentCategory == start)
            {
                Console.WriteLine(new String(   , level) + child.Name);
                recurseCategories(ref cl, child, level + 1);
            }
        }
    }

    public class Category
    {
        public string Name { get; set; }
        public Category ParentCategory { get; set; }
    }

}

输出。

test1
test4

输出应该是:

test1
   test 2
   test 3
test 4
   test 5
   test 6
   test 7

这是因为共享相同父节点的子节点之间没有关系。





相关问题
热门标签