2013-07-11 14 views
7

Mam listę struktur danych:Jak zbudować hierarchię za pomocą Linq do obiektu?

 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 
         }, 
       }; 
     } 

i chcę zbudować drzewa:

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" 
                  } 
                } 
              } 
            } 
          } 
        }; 
      } 

Jak zbudować drzewo z LINQ do obiektu? Mam do wykorzystania, ale to nie działa dokładnie tak, patrz poniżej:

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

Jeśli możesz zbudować drzewo z użyciem rodzaju ogólnego, udostępnij swoje przykłady. Podziękować! – LazyCatIT

Odpowiedz

15

Należy użyć rekurencji:

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

Dziękujemy za odpowiedź! Ale kiedy stosuję twój kod, podnoszą wyjątek "System.StackOverflowException". Możesz to sprawdzić ponownie. – LazyCatIT

+2

Może się zdarzyć, jeśli masz jakieś pozycje na liście 'z linkami cyklicznymi. Na przykład: [{{Id = 1, ParentId = 2}, {Id = 2, ParentId = 1}] (http://en.wikipedia.org/wiki/Cycle_graph) – YD1m

+0

Dodano poprawkę poniżej do obsługi przypadku, w którym ktoś ma węzeł główny z ParentId = Id –

0

samo jak wyżej tylko ten kod sprawdza dla przypadku, że węzeł główny ma ParentID, który pasuje do własnego identyfikatora.

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

To wykryłoby tylko przypadek, w którym 2 węzły bezpośrednio odnoszą się do siebie jako rodzice (# 1 -> # 2 -> # 1 -> itd.). Jeśli wprowadzisz trzeci węzeł (# 1 -> # 2 -> # 3 -> # 1 -> itd.), Cykl znów będzie się opierał. – BTownTKD

Powiązane problemy