CodeGym /Kurse /C# SELF /Filtern von Elementen

Filtern von Elementen

C# SELF
Level 29 , Lektion 0
Verfügbar

1. Grundlegende Methoden zum Filtern von Sammlungen

Filtern ist wie ein Sieb für Gold, nur dass wir statt Nuggets aus einer Sammlung nur die Elemente auswählen, die wir brauchen. Zum Beispiel haben wir eine Liste von Benutzern – wir wollen nur die Volljährigen finden, oder nur Studenten, oder nur die, die Kaffee mögen (also Programmierer). Das Auswählen passender Elemente ist eine superhäufige Aufgabe, die überall vorkommt: von der Arbeit mit Datenbanken bis zur Verarbeitung von Benutzereingaben.

Schauen wir uns verschiedene Wege an, wie man in C# filtern kann. Während wir das lernen, bauen wir unser Lern-Konsolenprogramm weiter aus und fügen Filter hinzu.

Manuelles Filtern mit einer Schleife

Starten wir mit der einfachsten und klassischsten Methode: Filtern mit foreach:


// Beispiel: Es gibt eine Liste von Zahlen, wir wollen nur die geraden auswählen

List<int> zahlen = new List<int> { 1, 2, 3, 4, 5, 6 };
List<int> geradeZahlen = new List<int>();

foreach (int zahl in zahlen)
{
    if (zahl % 2 == 0) // wenn die Zahl gerade ist
    {
        geradeZahlen.Add(zahl);
    }
}

Console.WriteLine("Gerade Zahlen:");
foreach (int n in geradeZahlen)
{
    Console.WriteLine(n);
}

So ein Weg funktioniert immer, ist leicht zu verstehen, aber nicht der kompakteste und auch nicht der "modernste".

Warum ist manuelles Filtern nicht immer praktisch?

Wenn du eine andere Sammlung hast, ein anderes Filterkriterium, oder gleich mehrere Filter schreiben musst – dann hast du schnell viel ähnlichen Code. Man wünscht sich mehr Kompaktheit, Lesbarkeit und Modularität.

2. Filtern nach komplexen Kriterien

Angenommen, wir haben eine Sammlung von Objekten. Nehmen wir das Beispiel mit Benutzern aus unserer wachsenden App.


public class Benutzer
{
    public string Name { get; set; }
    public int Alter { get; set; }
    public bool IstStudent { get; set; }
}

Wir deklarieren eine Liste von Benutzern:


List<Benutzer> benutzer = new List<Benutzer>
{
    new Benutzer { Name = "Anja", Alter = 17, IstStudent = true },
    new Benutzer { Name = "Boris", Alter = 21, IstStudent = false },
    new Benutzer { Name = "Vika", Alter = 19, IstStudent = true },
    new Benutzer { Name = "Gleb", Alter = 25, IstStudent = false }
};

Beispiel 1: Alle Studenten auswählen


List<Benutzer> studenten = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (user.IstStudent)
        studenten.Add(user);
}

Console.WriteLine("Liste der Studenten:");
foreach (Benutzer user in studenten)
{
    Console.WriteLine($"{user.Name} ({user.Alter})");
}

Beispiel 2: Nur volljährige Studenten auswählen


List<Benutzer> volljaehrige = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (user.Alter >= 18 && user.IstStudent)
        volljaehrige.Add(user);
}

Console.WriteLine("Volljährige Studenten:");
foreach (Benutzer user in volljaehrige)
{
    Console.WriteLine($"{user.Name} ({user.Alter})");
}

Und wenn die Filterkriterien dynamisch sind?

Man kann die Filterbedingungen in eigene Methoden auslagern und sie dann in der Schleife aufrufen:


bool IstVolljaehrig(Benutzer u) { return u.Alter >= 18; }
bool IstStudent(Benutzer u) { return u.IstStudent; }

List<Benutzer> gefiltert = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (IstVolljaehrig(user) && IstStudent(user))
        gefiltert.Add(user);
}

3. Filtern nach Schlüssel in Dictionaries

Listen und Arrays sind praktisch, aber oft arbeiten wir auch mit Dictionaries.

Angenommen, wir haben ein Dictionary, wo der Schlüssel der Name des Benutzers ist und der Wert sein Alter:


Dictionary<string, int> alterNachName = new Dictionary<string, int>
{
    ["Anja"] = 17,
    ["Boris"] = 21,
    ["Vika"] = 19,
    ["Gleb"] = 25
};

Aufgabe: Nur Benutzer 18+ auswählen


Dictionary<string, int> volljaehrige = new Dictionary<string, int>();
foreach (var pair in alterNachName)
{
    if (pair.Value >= 18)
        volljaehrige.Add(pair.Key, pair.Value);
}

Console.WriteLine("Volljährige:");
foreach (var pair in volljaehrige)
{
    Console.WriteLine($"{pair.Key}: {pair.Value} Jahre");
}

Aufgabe: Benutzer mit Namen, die mit "V" anfangen, auswählen


Dictionary<string, int> namenMitV = new Dictionary<string, int>();
foreach (var pair in alterNachName)
{
    if (pair.Key.StartsWith("V"))
        namenMitV.Add(pair.Key, pair.Value);
}

Console.WriteLine("Namen mit 'V':");
foreach (var pair in namenMitV)
{
    Console.WriteLine($"{pair.Key}: {pair.Value} Jahre");
}

4. Prinzipien des Filterns

Wie läuft der Filterprozess ab


┌──────────────────────────────────┐
│  Liste: [1, 2, 3, 4, 5, 6]       │
└──────────────────────────────────┘
         │
         ▼
    [Prüfung: n % 2 == 0]
         │
         ▼
┌──────────────────────────────────┐
│  Ergebnis: [2, 4, 6]             │
└──────────────────────────────────┘

Filter kombinieren: Nach verschiedenen Bedingungen filtern

Man kann auch nacheinander filtern, wenn man die Daten schrittweise auswählen will:


// Erstmal nur Studenten filtern
List<Benutzer> nurStudenten = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (user.IstStudent)
        nurStudenten.Add(user);
}

// Dann unter ihnen nur die Volljährigen auswählen
List<Benutzer> volljaehrigeStudenten = new List<Benutzer>();
foreach (Benutzer user in nurStudenten)
{
    if (user.Alter >= 18)
        volljaehrigeStudenten.Add(user);
}

Oder alles auf einmal:


List<Benutzer> volljaehrigeStudenten = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (user.IstStudent && user.Alter >= 18)
        volljaehrigeStudenten.Add(user);
}

Sortieren und andere Operationen

Sortieren kann man mit der Sort-Methode für Listen:


// Volljährige Studenten, sortiert nach Alter
volljaehrigeStudenten.Sort((a, b) => a.Alter.CompareTo(b.Alter));

Mehr zum Sortieren gibt's in der nächsten Vorlesung!

5. Filtern in Benutzerszenarien

1. Filtern von Benutzereingaben

Angenommen, unsere App nimmt eine Liste von Noten entgegen und soll alle "Fünfer" auswählen.


Console.Write("Gib die Noten mit Leerzeichen ein: ");
string eingabe = Console.ReadLine();

List<int> noten = new List<int>();
foreach (string s in eingabe.Split(' '))
{
    if (int.TryParse(s, out int note))
        noten.Add(note);
}

List<int> fuenfer = new List<int>();
foreach (int note in noten)
{
    if (note == 5)
        fuenfer.Add(note);
}

Console.WriteLine("Fünfer:");
foreach (var note in fuenfer)
{
    Console.WriteLine(note);
}

2. Filtern nach mehreren Bedingungen

Aufgabe: Wähle Benutzer-Studenten im Alter von 18 bis einschließlich 22 Jahren aus.


List<Benutzer> gefiltert = new List<Benutzer>();
foreach (Benutzer user in benutzer)
{
    if (user.IstStudent && user.Alter >= 18 && user.Alter <= 22)
        gefiltert.Add(user);
}

3. Filtern nach Vorhandensein eines Elements

Angenommen, wir haben eine Liste von Strings und wollen nur die auswählen, die die Teilzeichenkette ".net" enthalten (ohne Beachtung der Groß-/Kleinschreibung).


List<string> technologien = new List<string> { "C#", ".NET", "Java", "dotnet", "JavaScript" };

List<string> netTechs = new List<string>();
foreach (var tech in technologien)
{
    if (tech.ToLower().Contains(".net"))
        netTechs.Add(tech);
}

foreach (var tech in netTechs)
{
    Console.WriteLine(tech);
}

6. Besonderheiten und typische Fehler beim Filtern

Filtern wirkt einfach, aber hier kann man einiges falsch machen. Lass uns ein paar Besonderheiten anschauen.

Ändern der Ausgangssammlung

Wenn du die Ausgangssammlung filterst und dann nach dem Filtern ihren Inhalt änderst, – das Ergebnis bleibt gleich, wenn du schon eine neue Liste erstellt hast. Wenn du aber nur die Referenz auf die alte Liste gemerkt hast, können Änderungen an der Ausgangssammlung das Ergebnis beeinflussen.


List<int> gefiltert = new List<int>();
foreach (int n in zahlen)
{
    if (n > 2)
        gefiltert.Add(n);
}

// Wir ändern die Ursprungsliste
zahlen.Add(10);

foreach (var n in gefiltert)
{
    Console.WriteLine(n); // 10 kommt hier nicht rein
}

Ergebnis des manuellen Filterns

Das Ergebnis vom manuellen Filtern ist meistens eine neue veränderbare Liste (zum Beispiel List<T>), mit der du alles machen kannst – Elemente hinzufügen, löschen usw.

Filtern und Performance

Filter in Schleifen werden für jedes Element der Sammlung aufgerufen, also wenn die Funktion im Filter schwer ist – Vorsicht! Manchmal ist eine einfache foreach-Schleife besser, besonders wenn du komplexe Logik, Logging oder zusätzliche Aktionen brauchst.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION