Wie du mehrdimensionale Arrays in C# definierst

Und warum es wohl kein anderer C# Entwickler macht
Veröffentlicht: vor 3 monaten · Lesedauer ca. 7 Minuten

Wie bildet man eine Zahl in C# an?

Man schreibt sowas wie:

int n = 42;

Das war noch einfach 🙂

Wie bildet man eine Reihe von Zahlen ab?

Da könnte man bereits ein Array verwenden:

int[] numbers = new int[42];

Und schon kann man genau 42 Zahlen abbilden. Diese sind Standardmäßig mit 0 (der Zahl null) allokiert worden.

War bestimmt auch noch einfach 🙂

Wie bildet man aber jetzt eine Tabelle ab?

Um das zu lösen, wird ein mehrdimensionales Array benötigt. Für eine Tabelle braucht man zwei Dimensionen. Das kann man sich noch relativ einfach vorstellen.

Da unsere Welt dreidimensional ist, können wir uns auch noch ein dreidimensionales Array ziemlich gut vorstellen.

Alles darĂĽber hinaus wird aber schon ziemlich schwer vorstellbar. Vielleicht bist du in der Lage ohne weiteres in deinen Gedanken ein fĂĽnfdimensionales Array vorzustellen, ich bin es nicht. Jedenfalls nicht ohne viel Abstraktion, Fantasie und Konzentration.

Array aus Arrays – Jagged Array

Die einfachste Art ein mehrdimensionales Array abzubilden, ist einfach ein Array aus Arrays zu bilden. Das kann man natĂĽrlich beliebig auf die Spitze treiben.

Im Fachjargon wird es auch als jagged – also gezackt – Array bezeichnet. Lustigerweise heiĂźt es im Amerikanischen auch „besoffen„. Die Wortwahl war wahrscheinlich nicht ohne Grund 🙂

Man kann es wie folgt allokieren:

int[][] matrix = new int[3][];

Ein Array hat ja bekanntlich in allen C-Dialekten eine fest definierte Größe. Bei einem jagged Array definiert man lediglich die erste Ebene.

Beim Versuch beide Ebenen zu definieren, schimpft Visual Studio sofort. Das hier, geht also nicht:

int[][] matrix = new int[3][3];

Möchtest du das erreichen, musst du tatsächlich manuell jede „Zeile“ per Hand initialisieren:

int[][] matrix = new int[3][];
matrix[0] = new int[3];
matrix[1] = new int[3];
matrix[2] = new int[3];

So, und das jetzt mal fĂĽr ein 1000×1000 Array bitte 🙂

int[][] matrix = new int[1000][];
for (int i = 0; i < matrix.Length; i++)
{
	matrix[i] = new int[1000];
}

Geht auch, ist nur etwas umständlich, oder? 🙂

Mit diesem Array kommt man jetzt sowohl an eine „Zeile“, als auch an die Zahl selbst dran.

int[] vector = matrix[1];
int n = matrix[0][1];

Möchtest du durch das Array iterieren (also jeden Wert einmal „in die Hand nehmen“), musst du immer pro Dimension eine Schleife erstellen. Das sieht dann wie folgt aus:

foreach (int[] vect in matrix)
{
	foreach (int n in vect)
	{
		Console.WriteLine(n);
	}
}

Mit einer for-Schleife geht es aber auch:

for (int x = 0; x < matrix.Length; x++)
{
	for (int y = 0; y < matrix[x].Length; y++)
	{
		Console.WriteLine(matrix[x][y]);
	}
}

Bei einem jagged Array kann man sich übrigens darauf verlassen, dass man sich nicht auf eine einheitliche Größe verlassen darf 🙂

Da man die zweite Dimension unabhängig voneinander definieren kann, können die Größen mitunter stark variieren.

int[][] jagged = new int[8][];
jagged[0] = new int[8];
jagged[1] = new int[3];
jagged[2] = new int[5];
jagged[3] = new int[1];
jagged[4] = new int[7];
jagged[5] = new int[3];
jagged[6] = new int[3];
jagged[7] = new int[2];

Das Array sieht dann wie folgt aus:

Doch wie findet man heraus, wie viele Elemente insgesamt solch ein Array hat?

Glücklicherweise haben wir Linq 🙂

jagged.Sum(a => a.Length); // 32

Zweidimensionales Array – Rechteckiges Array

Wenn man sich bei einem jagged Array nicht auf die Größe verlassen darf, so kann man hier davon ausgehen, dass man keine unterschiedlichen Größen definieren darf.

Ein 2D Array, ist an dem Komma zwischen den rechteckigen Klammern sehr gut zu erkennen.

int[,] arr = new int[3,3];

Anders als beim jagged Array, kann man es auch direkt initialisieren. Hierzu kannst du eine der folgenden Varianten wählen:

int[,] arr1 = { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
int[,] arr2 = new[,] { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
int[,] arr3 = new int[,] { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
int[,] arr4 = new int[3, 3] { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };

Das hier, geht ĂĽbrigens zum GlĂĽck nicht:

var arr = { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };

Ich bevorzuge tatsächlich die längste Variante. Einfach um dem nächsten Programmierer (kann ja auch ich selbst sein – in ein paar Tagen oder Monaten) direkt darauf hinzuweisen, dass es sich um ein 3×3 Array handelt.

Während ein jagged Array noch zwei foreach Schleifen benötigt hat, reicht für ein mehrdimensionales Array eine foreach:

int[,] matrix = new int[3, 3] { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
foreach (int n in matrix)
{
	Console.WriteLine(n);
}

Was jedoch nicht funktioniert, ist der Zugriff auf eine „Zeile“ im Array. Bei der nächsten Zeile schimpft Visual Studio noch bevor man die Zeile zu Ende geschrieben hat 🙂

int[] vector = matrix[0];

Mehrdimensionale Arrays in der Praxis

Und jetzt kommt die Fangfrage. Welcher Array Typus wird in der Praxis verwendet?

Die bittere Wahrheit ist tatsächlich: Man verwendet kaum mehr Arrays.

Wirklich nicht.

In C# verwendet man Listen, bzw. Collections.

Klar, die sind bequemer. Listen sind Arrays auf Steroiden.

Es gibt aber auch keine Möglichkeit eine mehrdimensionale Liste zu erstellen.

Stattdessen verwendet man Listen aus Listen:

List<List<int>> matrix = new List<List<int>>();
matrix[0][0] = 42;

Listen verwendet man genauso wie jagged Arrays und sind (wie bereits erwähnt) gängige Praxis.

Als Softwareentwickler sollte man im Übrigen auch die Performance nicht außer Acht lassen. So sind mehrdimensionale Arrays tatsächlich langsamer als jagged Arrays.

Auch der FxCop hat frĂĽher dem Entwickler empfohlen mehrdimensionale Arrays zu meiden und stattdessen jagged Arrays zu verwenden.

Ich vermute, das ist auch der Grund, warum Microsoft uns keine mehrdimensionalen Listen zur Verfügung gestellt hat 🙂

Fazit – Mehrdimensionale Arrays

Fassen wir kurz zusammen:

// "echtes" Zweidimensionales Array
int[,] matrix = new int[3,3];

// Array aus Arrays - jagged array
int[][] table = new int[3][] { new int[3], new int[3], new int[3] };

// Liste aus Listen - C# Standard
List<List<int>> collection = new List<List<int>>();
... und was meinst du dazu?
Deine E-Mail-Adresse wird nicht veröffentlicht.