none
[VB] Eine n-hierarchische Auflistung in eine 1-hierarchische Auflistung konvertieren RRS feed

  • Allgemeine Diskussion

  • Liebe Kolleginnen und Kollegen,

    gehen wir von folgender Situation aus:

    • Wir haben eine Klasse Element, die eine Auflistung beliebiger Art vom Typ Element enthält.

    Class Element
        Childs As IEnumerable(Of Element)
    End Class

    • Nun haben wir eine Instanz Source einer Auflistung beliebiger Art vom Typ Element, mit 0 bis n Elementen, die jeweils 0 bis m Elemente enthalten. In einer Zielvariablen Instanz Destination einer dynamischen Auflistung vom Typ Element möchten wir nun alle in Source auf allen Ebenen befindliche Elemente auf eine Ebene auflisten.

    Public Source As IEnumerable(Of Element)
    Public Destination As IEnumerable(Of Element)

    • Beispielsweise:

    Source = 
        Element1
            Element1a
            Element1b
        Element2
        Element3
            Element3a
    
     ->
    
    Destination = 
        Element1
        Element1a
        Element1b
        Element2
        Element3
        Element3a

    Gegenstand: Konkreten Möglichkeiten, um diese Aufgabe zu bewältigen.

    Auf eure Ideen und Vorschläge freue ich mich.

    Ich selbst werfe folgende Methode in den Raum:

    Sub Convert(parent As Element) Destination.Add(parent) If parent.Childs.Count > 0 Then Array.ForEach(parent.Childs.ToArray(), Sub(x) Convert(x)) End Sub

    Diese Methode sollte dann wie folgt aufgerufen werden:

    Array.ForEach(Source.ToArray(), Sub(x) Convert(x))
    Donnerstag, 27. September 2018 00:28

Alle Antworten

  • Hi Martin,
    nachfolgend mal eine kleine Demo für den Fall, dass die Strukturtiefe variabel ist. Für Dich von Bedeutung kann die rekursive Methode GetDestination sein.

    Module Module1
      Sub Main()
        Try
          Dim c As New Demo
          c.Execute()
        Catch ex As Exception
          Console.WriteLine(ex.Message)
        End Try
        Console.WriteLine("weiter mit Taste")
        Console.ReadKey()
      End Sub
    
      Friend Class Demo
        Friend Sub Execute()
          ' Datenquelle laden
          Dim source As IEnumerable(Of Element) = GetData(1)
          ' Datenquelle anzeigen
          ShowData(1, source)
          ' Datenziel erzeugen
          Dim destination As IEnumerable(Of Element) = GetDestination(source)
          ' Datenziel anzeigen
          Console.WriteLine(" -------------- ")
          For Each e In destination
            Console.WriteLine(e.Name)
          Next
        End Sub
    
        Private Sub ShowData(level As Integer, s As IEnumerable(Of Element))
          For Each e In s
            Console.WriteLine(New String(" "c, level) & e.Name)
            ShowData(level + 1, e.SubElements)
          Next
        End Sub
    
        Private nr As Integer = 1
        Private rnd As New Random
    
        Private Function GetData(level As Integer) As List(Of Element)
          Dim res As New List(Of Element)
          For i = 1 To 10 - 2 * level
            Dim e As New Element() With {.Name = $"Element {nr}"}
            nr += 1
            If level < rnd.Next(1, 5) Then e.SubElements.AddRange(GetData(level + 1))
            res.Add(e)
          Next
          Return res
        End Function
    
        Private Iterator Function GetDestination(source As IEnumerable(Of Element)) As IEnumerable(Of Element)
          For Each e1 In source
            Yield e1
            For Each e2 In GetDestination(e1.SubElements)
              Yield e2
            Next
          Next
        End Function
      End Class
    
      Friend Class Element
        Public Property Name As String
        Public Property SubElements As List(Of Element) = New List(Of Element)
      End Class
    End Module


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Donnerstag, 27. September 2018 08:09