Geschachtelte Arrays (nested arrays)

 


Abstract:

 

Nested Arrays can be very useful for problems where the result is a series of arrays of different length. Making use of nested arrays in VBA is not a difficult task. We will show two versions by means of an example (Collatz sequence): The first one, involving a user-defined data type, is slightly longer but more understandable than the second one, which has to make use of type Variant.

 

 

Bei manchen Aufgaben ist es sinnvoll, das Ergebnis in einem geschachtelten Array zusammen­zu­stellen, also einem Array, dessen Elemente selbst Arrays sind.

 

Ein Beispiel soll dies veranschaulichen:

 

Für eine Liste von ganzen Zahlen sollen die Collatzfolgen ermittelt werden, die mit diesen Zahlen („Startzahlen“) beginnen.  (Falls Ihnen der Begriff der Collatzfolge nicht bekannt ist, können Sie sich auf dieser Homepage darüber informieren: s. Rubrik Excel-VBA | Übungsaufgaben).

 

Ist die Liste der Startzahlen z.B.

 

                6,  7, 8, 9

 

dann sähe das Ergebnis so aus:

 

6

3

10

5

16

8

4

2

1

                     

7

22

11

34

17

52

26

13

40

20

10

5

16

8

4

2

1

     

8

4

2

1

                               

9

28

14

7

22

11

34

17

52

26

13

40

20

10

5

16

8

4

2

1

 

Jede Zeile stellt eine Collatzfolge dar. Links (hier zur besseren Orientierung fett gedruckt) steht jeweils die Startzahl, rechts der Startzahl sind die Glieder der betreffenden Folge bis zur ersten auftretenden 1 aufgelistet.

 

Man sieht sofort, weshalb ein zweidimensionales Array schlecht geeignet wäre, dieses Ergebnis aufzunehmen: die Folgen sind unterschiedlich lang. Besser ist, wenn wir die einzelnen Folgen in eindimensionale Arrays unterschiedlicher Länge packen und diese Arrays dann wieder in ein Array einbringen. Wir haben dann ein eindimensionales Array, dessen Elemente selbst Arrays sind, also ein geschachteltes Array.

 

Im Folgenden werden zwei Varianten dieser Lösung gezeigt. Die erste Variante verwendet einen benutzerdefinierten Datentyp. Die zweite Variante verzichtet auf diesen Datentyp und ist deshalb etwas kürzer, hat aber den Nachteil, dass der Daten(un)typ Variant verwendet werden muss und dementsprechend die Klarheit und Wartbarkeit des Programms leidet.

 

Bevor wir die beiden Lösungen im Einzelnen betrachten, führen wir aber noch eine Funktion ein, die in beiden Varianten verwendet wird. Diese Funktion ermittelt die Collatzfolge für eine bestimmte Startzahl und liefert sie als Array von Long-Zahlen:

 

 

Public Function CollatzFolge(ByVal z As Long) As Long()

      

      Dim c() As Long

      Dim n As Integer

      n = 1

      ReDim c(1 To n)

      c(n) = z

      Do While z > 1

            n = n + 1

            ReDim Preserve c(1 To n)

            z = IIf(z Mod 2 = 0, z \ 2, 3 * z + 1)

            c(n) = z

      Loop

      CollatzFolge = c

 

End Function

 

 

 

 

Lösungsvariante 1: mit benutzerdefiniertem Datentyp

 

Die Funktion CollatzArray liefert ein eindimensionales Array, dessen Elemente vom Typ CA sind. Der Typ CA beinhaltet, wie die folgende Deklaration zeigt, ein eindimensionales Array von Long-Zahlen. Jede Ausprägung dieses Typs kann demnach eine Collatzfolge aufnehmen.

 

Type CA

      el() As Long

End Type

 

Die Startzahlen der gewünschten Folgen werden der Funktion im Array z übergeben.

 

 

Public Function CollatzArray(ByRef z() As Long) As CA()

 

      Dim c() As CA

      ReDim c(LBound(z) To UBound(z))

      Dim i As Integer

      For i = LBound(z) To UBound(z)

            c(i).el = CollatzFolge(z(i))

      Next i

      CollatzArray = c

 

End Function

 

 

 

 

Lösungsvariante 2: ohne benutzerdefiniertem Datentyp

 

Hier verzichten wir auf den benutzerdefinierten Datentyp CA, müssen dafür aber ein Array vom Typ Variant verwenden, wenn wir die Arrays für die einzelnen Folgen in einem übergeordneten Array zusammenfassen wollen. Die Programmierung wird damit weniger deutlich bzw. anfälliger für Missverständnisse.

 

 

Public Function CollatzArray2(ByRef z() As Long) As Variant

 

      Dim f() As Variant

      ReDim f(LBound(z) To UBound(z))

      Dim i As Integer

      For i = LBound(z) To UBound(z)

          f(i) = CollatzFolge(z(i))

      Next i

      CollatzArray2 = f

 

End Function