【问题标题】:Multilevel parent child relation sorting using Linq c#使用Linq c#的多级父子关系排序
【发布时间】:2015-05-19 23:16:16
【问题描述】:

我有一个列表,我需要将它排序到这个层次结构

{ Id=1, ParentId = null, Name = "Item1", Type="0"}
   { Id=2, ParentId = 1, Name = "ItemChild1", Type="1"}
   { Id=3, ParentId = 1, Name = "ItemChild2", Type="1"}
        { Id=4, ParentId = 3, Name = "ItemGrandChild1", Type="2"}
   { Id=5, **ParentId = 1**, Name = "ItemGrandChild2", Type="2"}

{ Id=6, ParentId = null, Name = "Item7", Type="0"}
...

与正常的父子关系不同,这里

Type2 的项可以是 Type1 或 Type0 的子项

所有的 Id 都是 guids

我看到可能会使用 Linq 在子父排序上堆叠答案。但我的情况不同。 使用 Linq 的任何优雅方式?

【问题讨论】:

    标签: c# asp.net linq list guid


    【解决方案1】:

    如果我是你,我会放弃尝试使用 linq 或 sql 对其进行排序。抽象可能会有所帮助,但在这种复杂的情况下,它们只会妨碍您。

    如果您只编写自己的分拣机,您将节省大量时间。

    class MyCompare : IComparer<MyObject>
    {
      public int Compare(x1, x2)
      {
          if (x1.parent == parent1 && x2.parent == parent2)
            return 1;
          if (x1.parent == x2.parent)
            return 0;
          //ect 
      }
    }
    List<MyObject> list = GetWeirdObjects();
    list.Sort(new MyCompare());
    

    【讨论】:

      【解决方案2】:

      创建一个查找以快速找到孩子并将它们投影到父集合。据我所知,只要您的孩子知道哪个元素是他们的父母,这根本不取决于您的孩子是否有不同的类型。

      public class TreeItem
      {
          public int Id { get; set; }
          public int? ParentId { get; set; }
          public IEnumerable<TreeItem> Children { get; set; }
      
          public void PrintAllChildren()
          { 
              this.PrintAllChildren(0);
          }
      
          private void PrintAllChildren(int indent)
          {
              Debug.WriteLine("{1}Item id: {0}", this.Id, string.Concat(Enumerable.Repeat<int>(0, indent).Select(i => " ")));
              if (this.Children != null)
                  foreach (var item in this.Children)
                      item.PrintAllChildren(indent + 1);
          }
      }
      
      public static class TreeItemExtension
      {
          public static IEnumerable<TreeItem> GetAsTree(this IEnumerable<TreeItem> data)
          {
              var lookup = data.ToLookup(i => i.ParentId);
              return lookup[null].Select(i => {
                  i.FillChildren(lookup);
                  return i;
              });
          }
          private static TreeItem FillChildren(this TreeItem item, ILookup<int?, TreeItem> lookup)
          {
              item.Children = lookup[item.Id].Select(i => i.FillChildren(lookup));
              return item;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-05
        相关资源
        最近更新 更多