Ihr Notizbuch wird viele Notizen haben, und vorher wissen Sie nicht, wie viele. Für jede Notiz eine eigene Variable anzulegen, geht nicht. Sie brauchen eine Variable, die beliebig viele Werte aufnimmt: eine Liste.
Eine Liste anlegen und füllen
// einkauf.cs
List<string> einkauf = ["Brot", "Milch"];
einkauf.Add("Äpfel");
Console.WriteLine($"Auf der Liste stehen {einkauf.Count} Dinge.");
Console.WriteLine($"Das erste ist {einkauf[0]}, das letzte {einkauf[einkauf.Count - 1]}.");
foreach (string ding in einkauf)
{
Console.WriteLine($"- {ding}");
}
Auf der Liste stehen 3 Dinge.
Das erste ist Brot, das letzte Äpfel.
- Brot
- Milch
- Äpfel
Der Reihe nach:
List<string>ist der Typ „Liste von Texten“. In den spitzen Klammern steht, was in der Liste liegt. Eine Liste von ganzen Zahlen wäreList<int>.- In eckigen Klammern stehen die Einträge, mit denen die Liste beginnt. Eine leere Liste schreiben Sie als
[]. Addhängt einen Eintrag hinten an.Countist die Anzahl der Einträge.einkauf[0]ist der erste Eintrag. Listen zählen ab 0, nicht ab 1. Der letzte Eintrag hat deshalb die NummerCount - 1.foreachgeht die Liste von vorn bis hinten durch. In jedem Durchlauf steht der aktuelle Eintrag in der Variablending.
Fragen Sie nach einer Nummer, die es nicht gibt, etwa einkauf[3] bei drei Einträgen, bricht das Programm mit einer
ArgumentOutOfRangeException ab. Prüfen Sie Nummern deshalb vorher gegen Count.
Nummerieren mit for
Menschen zählen ab 1, Listen ab 0. Wenn Sie Einträge mit Nummern zeigen wollen, nehmen Sie for und rechnen eins dazu:
// nummeriert.cs
List<string> aufgaben = ["Steuer abgeben", "Fahrrad flicken", "Oma anrufen"];
for (int i = 0; i < aufgaben.Count; i++)
{
Console.WriteLine($"{i + 1}. {aufgaben[i]}");
}
1. Steuer abgeben
2. Fahrrad flicken
3. Oma anrufen
Die Bedingung heißt i < aufgaben.Count, nicht <=. Bei drei Einträgen läuft i also von 0 bis 2, genau die gültigen Nummern.
Einträge entfernen
// entfernen.cs
List<string> aufgaben = ["Steuer abgeben", "Fahrrad flicken", "Oma anrufen"];
aufgaben.Remove("Fahrrad flicken");
aufgaben.RemoveAt(0);
foreach (string aufgabe in aufgaben)
{
Console.WriteLine(aufgabe);
}
Console.WriteLine(aufgaben.Contains("Oma anrufen"));
Oma anrufen
True
Remove sucht einen Eintrag mit genau diesem Text und entfernt ihn. RemoveAt entfernt den Eintrag an einer Nummer, hier die 0, also
den ersten. Die Einträge dahinter rücken auf. Contains sagt, ob ein Eintrag mit genau diesem Text in der Liste steht.
Suchen
Für eine Suche in Notizen ist „genau dieser Text“ zu streng. Sie wollen alle Einträge, in denen ein Suchwort irgendwo vorkommt, egal ob
groß oder klein geschrieben. Das kann Contains auch für einen einzelnen Text:
// suchen.cs
List<string> notizen = ["Zahnarzt am Dienstag", "Brot kaufen", "Dienstreise vorbereiten", "Geburtstag von Tom"];
string suche = "dienst";
int treffer = 0;
foreach (string notiz in notizen)
{
if (notiz.Contains(suche, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(notiz);
treffer++;
}
}
Console.WriteLine($"{treffer} Treffer für \"{suche}\".");
Zahnarzt am Dienstag
Dienstreise vorbereiten
2 Treffer für "dienst".
notiz.Contains(suche, ...) fragt, ob das Suchwort in diesem einen Text vorkommt. StringComparison.OrdinalIgnoreCase sagt: „Groß-
und Kleinschreibung nicht beachten.“ Der Name ist lang, aber Ihr Editor ergänzt ihn, sobald Sie die ersten Buchstaben tippen.
Neben Listen gibt es Arrays, geschrieben etwa string[] tage = ["Mo", "Di", "Mi"];. Sie funktionieren ähnlich, haben aber eine
feste Länge. Für Daten, die wachsen sollen, ist die Liste die bessere Wahl. Arrays begegnen Ihnen in Lektion 10 wieder.
Übung 1
Schreiben Sie namen.cs. Das Programm fragt so lange nach Namen, bis eine leere Zeile kommt, und sammelt sie in einer Liste. Danach
schreibt es, wie viele Namen es sind, und listet sie nummeriert auf.
Lösung 1
// namen.cs
List<string> namen = [];
while (true)
{
Console.Write("Name (leer = fertig): ");
string name = Console.ReadLine() ?? "";
if (name == "")
{
break;
}
namen.Add(name);
}
Console.WriteLine($"{namen.Count} Namen:");
for (int i = 0; i < namen.Count; i++)
{
Console.WriteLine($"{i + 1}. {namen[i]}");
}
Name (leer = fertig): Ada
Name (leer = fertig): Linus
Name (leer = fertig): Grace
Name (leer = fertig):
3 Namen:
1. Ada
2. Linus
3. Grace
Die Liste wird vor der Schleife angelegt, damit sie nach der Schleife noch da ist, genau wie die Summe in Lektion 6.
Übung 2
Erinnern Sie sich an die Anleitung für den wörtlichen Helfer aus Lektion 1? Jetzt schreiben Sie sie in C#. Nehmen Sie diese Liste:
List<int> zahlen = [4, 17, 9, 23, 8];
Schreiben Sie groesste.cs, das die größte Zahl findet und ausgibt, ohne fertige Hilfsmittel, nur mit einer Schleife und einem if.
Geben Sie danach auch den Durchschnitt aus.
Lösung 2
// groesste.cs
List<int> zahlen = [4, 17, 9, 23, 8];
if (zahlen.Count == 0)
{
Console.WriteLine("Die Liste ist leer.");
}
else
{
int groesste = zahlen[0];
int summe = 0;
foreach (int zahl in zahlen)
{
if (zahl > groesste)
{
groesste = zahl;
}
summe += zahl;
}
double durchschnitt = (double)summe / zahlen.Count;
Console.WriteLine($"Die größte Zahl ist {groesste}.");
Console.WriteLine($"Der Durchschnitt ist {durchschnitt}.");
}
Die größte Zahl ist 23.
Der Durchschnitt ist 12,2.
Das ist Schritt für Schritt die Anleitung aus Lektion 1, einschließlich der leeren Liste. Für den Durchschnitt teilen Sie die Summe
(61) durch die Anzahl (5). Wären beide int, ergäbe das nach der Ganzzahl-Division aus Lektion 4 nur 12. (double)summe macht aus der
Summe vorher eine Zahl mit Nachkommastellen. Wie in Lektion 4 steht dort je nach Spracheinstellung 12,2 oder 12.2.
C# bringt für solche Aufgaben auch fertige Werkzeuge mit, etwa zahlen.Max(). Sie lernen sie im Aufbaukurs kennen. Einmal selbst
geschrieben, wissen Sie aber, was darin passiert.
Übung 3
Schreiben Sie liste-durchsuchen.cs. Es beginnt mit einer Liste von fünf Notizen Ihrer Wahl, fragt nach einem Suchwort und zeigt alle
Notizen, die es enthalten, egal ob groß oder klein geschrieben. Gibt es keinen Treffer, schreibt es „Nichts gefunden.“
Lösung 3
// liste-durchsuchen.cs
List<string> notizen = ["Zahnarzt am Dienstag", "Brot kaufen", "Dienstreise vorbereiten", "Geburtstag von Tom", "Reifen wechseln"];
Console.Write("Wonach suchen Sie? ");
string suche = Console.ReadLine() ?? "";
bool gefunden = false;
foreach (string notiz in notizen)
{
if (notiz.Contains(suche, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine($"- {notiz}");
gefunden = true;
}
}
if (!gefunden)
{
Console.WriteLine("Nichts gefunden.");
}
Wonach suchen Sie? brot
- Brot kaufen
Statt eines Zählers merkt sich hier eine bool-Variable, ob es mindestens einen Treffer gab. Beides ist richtig. Was passiert, wenn
Sie gar nichts eingeben und gleich Enter drücken? Ein leerer Text steckt in jedem Text, also erscheinen alle Notizen. Für eine Suche ist
das sogar praktisch. Im Notizbuch werden Sie es trotzdem abfangen.
Was Sie jetzt können
- Sie legen eine
List<string>oderList<int>an, auch leer mit[]. - Sie fügen mit
Addhinzu, zählen mitCount, lesen mit[nummer]und entfernen mitRemoveundRemoveAt. - Sie wissen, dass Listen ab 0 zählen, und zeigen trotzdem Nummern ab 1 an.
- Sie gehen mit
foreachundforüber eine Liste. - Sie suchen mit
ContainsundStringComparison.OrdinalIgnoreCase. - Sie haben Ihren ersten Algorithmus selbst geschrieben.
Weiterlesen
- Data collections: Listen in Microsofts Tutorial-Reihe, mit Sortieren und Suchen.
- Store and iterate through sequences of data using Arrays and the foreach statement in C#:
ein Modul zu Arrays und
foreach.