2013-07-11 11 views
7

私は、データ構造のリストを持っている:どのようにオブジェクトにLinqを使用して階層を構築するのですか?

 public List<Personal> Personals() 
     { 
      return new List<Personal> 
       { 
        new Personal 
         { 
          Id = 0, 
          Name = "Name 0" 
         }, 
        new Personal 
         { 
          Id = 1, 
          Name = "Name 1", 
          ParentId = 0 
         }, 
        new Personal 
         { 
          Id = 2, 
          Name = "Name 2", 
          ParentId = 0 
         }, 
        new Personal 
         { 
          Id = 3, 
          Name = "Name 3", 
          ParentId = 0 
         }, 
        new Personal 
         { 
          Id = 4, 
          Name = "Name 4", 
          ParentId = 1 
         }, 
        new Personal 
         { 
          Id = 5, 
          Name = "Name 5", 
          ParentId = 1 
         }, 
        new Personal 
         { 
          Id = 6, 
          Name = "Name 6", 
          ParentId = 2 
         }, 
        new Personal 
         { 
          Id = 7, 
          Name = "Name 7", 
          ParentId = 2 
         }, 
        new Personal 
         { 
          Id = 8, 
          Name = "Name 8", 
          ParentId = 4 
         }, 
        new Personal 
         { 
          Id = 9, 
          Name = "Name 9", 
          ParentId = 4 
         }, 
       }; 
     } 

を、私はツリーを構築したい:

public List<Tree> Trees() 
      { 
       return new List<Tree> 
        { 
         new Tree 
          { 
           Id = 0, 
           Name = "Name 0", 
           List = new List<Tree> 
            { 
             new Tree 
              { 
               Id = 1, 
               Name = "Name 1", 
               List = new List<Tree> 
                { 
                 new Tree 
                  { 
                   Id = 4, 
                   Name = "Name 4" 
                  }, 
                 new Tree 
                  { 
                   Id = 5, 
                   Name = "Name 5" 
                  } 
                } 
              } 
            } 
          } 
        }; 
      } 

どのオブジェクトにきゅうにツリーを構築するのですか?私が使用する必要がありますが、それは正確に動作しません、以下を参照:

public List<Tree> GetTree(List<Personal> list) 
     { 
      var listFormat = list.Select(x => new Tree 
       { 
        Id = x.Id, 
        Name = x.Name, 
        ParentId = x.ParentId 
       }).ToList(); 

      var lookup = listFormat.ToLookup(f => f.ParentId); 
      foreach (var tree in listFormat) 
      { 
       tree.List = lookup[tree.Id].ToList(); 
      } 

      return listFormat; 
     } 
+0

汎用タイプを使用してツリーを構築できる場合は、例を共有してください。感謝! – LazyCatIT

答えて

15

あなたは再帰を使用する必要があります。

ルートノードは、Aがある場合のためにのみ、このコードをチェック同上
public void SomeMethod() { 
    // here you get your `list` 
    var tree = GetTree(list, 0); 
} 

public List<Tree> GetTree(List<Personal> list, int parent) { 
    return list.Where(x => x.ParentId == parent).Select(x => new Tree { 
     Id = x.Id, 
     Name = x.Name, 
     List = GetTree(list, x.Id) 
    }).ToList(); 
} 
+0

あなたの答えをありがとう!しかし、あなたのコードを適用すると、例外 "System.StackOverflowException"が発生します。再度確認することができます。 – LazyCatIT

+2

巡回リンクで 'list'に項目があると起こります。例:[{{Id = 1、ParentId = 2}、{Id = 2、ParentId = 1}](http://en.wikipedia.org/wiki/Cycle_graph) – YD1m

+0

誰かがParentId = Idのルートノードを持っている –

0

自身のIDと一致するParentID。

public void SomeMethod() 
    { 
     // here you get your `list` 
     var tree = GetTree(list, 0); 
    } 

    public List<Tree> GetTree(List<Personal> list, int parent) 
    { 
     return list.Where(x => x.ParentId == parent).Select(x => new Tree 
     { 
      Id = x.Id, 
      Name = x.Name, 
      List = x.ParentId != x.Id ? GetTree(list, x.Id) : new List<Tree>() 
     }).ToList(); 
    } 
+1

これは、2つのノードがお互いを親として直接参照するケース(#1->#2->#1->など)を検出するだけです。 3番目のノード(#1 - >#2 - >#3 - >#1 - > etc)を導入すると、サイクルは再び頭を後にします。 – BTownTKD

関連する問題