2016-05-11 23 views
0

Ich brauche eine rekursive Funktion in C# zu schreiben, die Daten in der Konsole in der folgenden Baumstruktur gedruckt werden:Ausgabeliste in Baumstruktur

-Continent 
--Country 
---Province 
----City1 
----- Suburb4 
------ House3 
----City2 
----- Suburb1 
----- Suburb2 
------ House1 
------ House6 
----- Suburb3 
------ House4 
------ House5 

ich einen Dataset Listenbereich habe wie folgt:

ID Description ParentID 
1 Continent Null 
2 Country  1 
3 Province 2 
4 City1  3 
5 Suburb1  6 
6 City2  3 
7 Suburb2  6 
8 Suburb3  6 
9 Suburb4  4 
10 House1  7 
11 House3  9 
12 House4  8 
13 House5  8 
14 House6  7 

Wie mache ich den Code unten erstellen diese Ausgabe?

class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Press any key to start..."); 
      Console.ReadKey(true); 

     var area = new List<Areas>(); 
     area = PopulateList(area); 

     area.Sort((s1,s2) => s1.ParentID.CompareTo(s2.ParentID)); 

     PrintData(area); 

     Console.WriteLine("Press any key to exit..."); 
     Console.ReadKey(true); 

    } 


    private static void PrintData(List<Areas> area) 
    { 
     Console.WriteLine("-" + area[0].Description); 
     string[] array = new string[13]; 

     foreach (var item in area) 
     { 
      string[] children = GetChildren(area, item); 
      if (children != null) 
      { 
       int count = 0; 
       foreach (var child in children) 
       { 
        if (child != null) 
        { 
         for (int i = 0; i <= count +1; i++) 
         { 
          Console.Write("-"); 
         } 

         int count2 = 0; 
         foreach (string x in array) 
         { 
          if ((x != null) && (x.Contains(children[count]))) 
          { 

          } 
          else 
          { 
           if (children[count2] != null) 
           { 
            Console.WriteLine(children[count2]); 

            array[count2] = children[count2]; 
            count2++; 
           } 
          } 
         } 
         count++; 

        } 
       } 
      } 
     } 

    } 

    private static string[] GetChildren(List<Areas> areas, Areas item) 
    { 
     string[] children = new string[13]; 
     int count = 0; 
     foreach (var area in areas) 
     { 
      if ((item.ID == area.ParentID) && (area.ParentID != 0)) 
      { 
       children[count] = area.Description; 
       count++; 

       foreach (var area2 in areas) 
       { 
        if ((area.ID == area2.ParentID) && (area2.ParentID != 0)) 
        { 
         children[count] = area2.Description; 
         //count++; 
         foreach (var area3 in areas) 
         { 
          if ((area.ID == area3.ParentID) && (area3.ParentID != 0)) 
          { 
           children[count] = area3.Description; 
           //count++; 
          } 
         } 
        } 
       } 
      } 

     } 
     return children; 
    } 

und ich bin eine Ausgabe wie folgt erhalten:

Ich habe folgend versucht

-Continent 
--Country 
Province 
---Country 
Province 
--Province 
City2 
---Province 
... 

Antwort

1

Die folgende tut, was Sie wollen. Ich habe die Daten in eine generische Liste geladen, aber das Prinzip ist das gleiche

private List<Entity> _entities = new List<Entity>(); 


    private void Form1_Load(object sender, EventArgs e) 
    { 

     _entities.Add(new Entity(1, "Continent", null)); 
     _entities.Add(new Entity(2, "Country", 1)); 
     _entities.Add(new Entity(3, "Province", 2)); 
     _entities.Add(new Entity(4, "City1", 3)); 
     _entities.Add(new Entity(5, "Suburb1", 6)); 
     _entities.Add(new Entity(6, "City2", 3)); 
     _entities.Add(new Entity(7, "Suburb2", 6)); 
     _entities.Add(new Entity(8, "Suburb3", 6)); 
     _entities.Add(new Entity(9, "Suburb4", 4)); 
     _entities.Add(new Entity(10, "House1", 7)); 
     _entities.Add(new Entity(11, "House3", 9)); 
     _entities.Add(new Entity(12, "House4", 8)); 
     _entities.Add(new Entity(13, "House5", 8)); 
     _entities.Add(new Entity(14, "House6", 7)); 

     var parent = _entities.Find((x) => x.ParentId == 0); 
     EnumerateChildren(parent, 1); 
    } 

    private void EnumerateChildren(Entity thisEntity, int level) 
    { 
     Debug.WriteLine(new string('-', level) + thisEntity.Name); 
     foreach (var child in _entities.FindAll((x) => x.ParentId == thisEntity.Id).OrderBy(x => x.Id)) 
     { 
      EnumerateChildren(child, level + 1); 
     } 
    } 

    private class Entity 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public int ParentId { get; set; } 
     public Entity(int id, string name, int? parentId) 
     { 
      this.Id = id; 
      this.ParentId = parentId.HasValue ? Convert.ToInt32(parentId) : 0; 
      this.Name = name; 
     } 
    } 
+1

Danke @Matt, funktioniert perfekt :) –

1

Ich würde die Umgebungsinfos in einem Dictionary<int, List<Area>> laden, wo die int Schlüssel einen ParentID und den List<Area> Wert steht für alle Kinder Bereiche der gegebenen darstellt ParentID.

zB:

struct Area { 
    public int ID; 
    public string Description; 
    public int? ParentID; 
} 

void OutputAreasTree() { 
    IEnumerable<Area> areas = GetAreasFromDataSource(); 
    OutputAreasTreeFromNode(LoadAreasByParentID(areas), areasByParentID[0][0], 1); 
} 

Dictionary<int, List<Area>> LoadAreasByParentID(IEnumerable<Area> areas) { 
    Dictionary<int, List<Area>> areasByParentID = new Dictionary<int, List<Area>>(); 
    foreach (Area area in areas) { 
     int parentID = area.ParentID ?? 0; // use 0 as the ParentID of the root 
     List<Area> children; 
     if (!areasByParentID.TryGetValue(parentID, out children)) { 
      children = new List<Area>(); 
      areasByParentID.Add(parentID, children); 
     } 
     children.Add(area); 
    } 
    return areasByParentID; 
} 

void OutputAreasTreeFromNode(Dictionary<int, List<Area>> areasByParentID, Area area, int depth) { 
    for (int i = 0; i < depth; i++) 
     Console.Write('-'); 
    Console.WriteLine(area.Description); 
    List<Area> children; 
    if (areasByParentID.TryGetValue(area.ID, out children)) { 
     foreach (Area child in children) 
      OutputAreasTreeFromNode(areasByParentID, child, depth+1); 
    } 
} 

Hoffe, es hilft.

+0

Danke. Fehlt Ihnen der Code für LoadAreasByParentID? –

+1

Ich habe es bewusst weggelassen, weil ich dachte, es würde beinhalten, die Bereiche von einer Quelle zu bekommen. Ich werde jedoch meine Antwort bearbeiten, und ich werde die Implementierung von LoadAreasByParentID hinzufügen, die eine IEnumerable als Eingabe verwendet, und lassen Sie nur das Sammeln der Bereichsliste aus Ihrer Quelle. – Fede