Een gewone array is een rij van waarden achter elkaar. Maar soms wil je je gegevens niet in één rij, maar in een tabel met rijen en kolommen bewaren. Denk aan de punten van een aantal studenten voor verschillende vakken. Daarvoor gebruik je een twee-dimensionale array (kortweg een 2D-array).
We willen de resultaten van onderstaande leerlingen tonen. Er zijn 5 studenten en per student 3 testen (de vakken Wiskunde, Fysica en Frans):
| Wiskunde | Fysica | Frans | |
|---|---|---|---|
| Emma | 7 | 8 | 6 |
| Louise | 10 | 10 | 10 |
| Marie | 4 | 3 | 5 |
| Elise | 6 | 1 | 9 |
| Lea | 5 | 10 | 7 |
Welke arrays hebben we nodig? De namen van de studenten en de namen van de vakken zijn gewone (één-dimensionale) arrays:
string[] studenten = new string[5] { "Emma", "Louise", "Marie", "Elise", "Lea" };
string[] vakken = new string[3] { "Wiskunde", "Fysica", "Frans" };
De punten zelf passen niet in één rij: elke student heeft drie punten. Die bewaren we in een 2D-array.
Een 2D-array declareer je met een komma tussen de vierkante haakjes. Bij het aanmaken geef je twee afmetingen op: eerst het aantal rijen, dan het aantal kolommen.
int[,] punten = new int[5, 3];
Dit maakt een tabel met 5 rijen en 3 kolommen, in totaal 15 vakjes, allemaal
nog op 0.
Een element spreek je aan met twee indexen tussen vierkante haakjes:
eerst de rij-index, dan de kolom-index, gescheiden door een komma. Net
als bij een gewone array beginnen de indexen bij 0. De punten van Emma
(rij 0) vul je zo in:
punten[0, 0] = 7; // Emma, Wiskunde
punten[0, 1] = 8; // Emma, Fysica
punten[0, 2] = 6; // Emma, Frans
// ... de overige rijen op dezelfde manier invullen
Je kan een 2D-array ook meteen vullen bij het declareren. Je geeft dan per rij de waarden mee, elk groepje tussen accolades:
int[,] punten = new int[5, 3] {
{ 7, 8, 6 },
{ 10, 10, 10 },
{ 4, 3, 5 },
{ 6, 1, 9 },
{ 5, 10, 7 }
};
Elke regel binnen de accolades is één rij: { 7, 8, 6 } zijn de drie punten
van Emma.
GetLengthBij een gewone array gebruik je Length om het aantal elementen te kennen. Bij
een 2D-array werkt dat niet zoals je verwacht: punten.Length geeft het
totaal aantal elementen terug (hier 15), niet het aantal rijen of
kolommen.
Gebruik daarom GetLength:
| Uitdrukking | Betekenis | Waarde |
|---|---|---|
punten.GetLength(0) | aantal rijen (studenten) | 5 |
punten.GetLength(1) | aantal kolommen (vakken) | 3 |
punten.Length | totaal aantal elementen | 15 |
Gebruik bij een 2D-array dus
GetLength(0)enGetLength(1), nietLength.
Om alle vakjes te bezoeken, heb je twee indexen nodig: één voor de rij en één voor de kolom. Daarvoor gebruik je een geneste for-lus: de buitenste lus loopt over de rijen, de binnenste over de kolommen.
Zo druk je de hele tabel af, met de naam van de student vooraan. De "\t" is
een tab die de kolommen mooi uitlijnt:
for (int i = 0; i < punten.GetLength(0); i++) {
Console.Write(studenten[i] + "\t");
for (int j = 0; j < punten.GetLength(1); j++) {
Console.Write(punten[i, j] + "\t");
}
Console.WriteLine();
}
De buitenste lus zet i op de rij van een student en schrijft eerst zijn naam.
De binnenste lus loopt dan met j over de drie vakken en schrijft elk punt
punten[i, j]. Na elke rij springt Console.WriteLine() naar een nieuwe regel.
Het gemiddelde van één student is de som van zijn punten gedeeld door het aantal
vakken. We tellen dus per rij alle kolommen op. Let op: om een kommagetal te
krijgen, casten we de gehele som naar double vóór de deling.
int totaal;
double gemiddelde;
for (int i = 0; i < punten.GetLength(0); i++) {
totaal = 0;
for (int j = 0; j < punten.GetLength(1); j++) {
totaal += punten[i, j];
}
gemiddelde = Math.Round((double)totaal / punten.GetLength(1), 2);
Console.WriteLine(studenten[i] + ":\t" + gemiddelde);
}
Voor elke rij i zetten we totaal eerst terug op 0, tellen we de drie
punten op, en delen we door punten.GetLength(1) (het aantal kolommen). Met
Math.Round(..., 2) ronden we af op twee cijfers na de komma.
Het gemiddelde per vak werkt net andersom: nu tellen we per kolom alle rijen
op. De buitenste lus loopt dus over de kolommen (GetLength(1)), de
binnenste over de rijen (GetLength(0)). Merk op hoe de indexen van plaats
wisselen in punten[j, i]:
int totaal;
double gemiddelde;
for (int i = 0; i < punten.GetLength(1); i++) {
totaal = 0;
for (int j = 0; j < punten.GetLength(0); j++) {
totaal += punten[j, i];
}
gemiddelde = Math.Round((double)totaal / punten.GetLength(0), 2);
Console.WriteLine(vakken[i] + ":\t" + gemiddelde);
}
Onthoud: de eerste index is altijd de rij, de tweede de kolom. Of je nu per rij of per kolom optelt, het is gewoon een kwestie van kiezen welke index de buitenste lus stuurt en welke de binnenste.