CodeGym /Kurse /C# SELF /Elemente in Kollektionen in C# suchen

Elemente in Kollektionen in C# suchen

C# SELF
Level 29 , Lektion 1
Verfügbar

1. Grundlegende Suchmöglichkeiten in Kollektionen

Oft werden die Wörter „Suche“ und „Filterung“ als Synonyme verstanden, aber beim Programmieren gibt es da schon Unterschiede.

  • Filterung – das ist, wenn wir alle Elemente einer Kollektion bekommen wollen, die einer bestimmten Bedingung entsprechen (zum Beispiel alle Zahlen größer als 10).
  • Suche – meistens brauchen wir da nur ein Element: das erste passende, ein Element mit bestimmtem Wert oder einfach nur wissen, ob es überhaupt in der Kollektion ist.

Wenn man das mit einer Bibliothek vergleicht: Filterung ist wie alle Bücher zum Thema „Weltraum“ zu sammeln, und Suche ist wie zu fragen: „Habt ihr das Buch ‘Ulysses’?“ oder „Wo steht das erste Buch mit blauem Einband?“.

Alle wichtigen .NET-Kollektionen (Arrays, Listen, Sets, Dictionaries usw.) unterstützen verschiedene Möglichkeiten, Elemente zu suchen oder auf Vorhandensein zu prüfen.

Schauen wir uns die gängigsten Methoden an:

Kollektion Vorhandensein prüfen Index finden Element finden Nach Schlüssel suchen
List<T>
Contains
IndexOf
Find
-
T[]
(Array)
Contains
/
Array.IndexOf
Array.IndexOf
- -
HashSet<T>
Contains
- - -
Dictionary<TKey,V>
ContainsKey
,
ContainsValue
- - Hat Indexer
[key]

Manche Methoden gibt’s nur bei bestimmten Typen.

2. Suche in Listen: List<T>

List<T> ist eine der flexibelsten Kollektionen, um Elemente mit beliebigem Zugriff zu speichern. Hier die wichtigsten Suchmethoden:

Vorhandensein prüfen: Contains

Mit dieser Methode findest du raus, ob ein bestimmtes Element in der Liste ist:

List<string> fruits = new List<string> { "Apfel", "Banane", "Kiwi" };
bool hasKiwi = fruits.Contains("Kiwi"); // true
bool hasMango = fruits.Contains("Mango"); // false
Console.WriteLine(hasKiwi); // True

Unter der Haube geht Contains einfach die Kollektion durch und nutzt Equals.

Index suchen: IndexOf

Wenn du wissen willst, wo genau ein Element steht (seine Nummer in der Liste):

int index = fruits.IndexOf("Banane"); // 1 (nullbasiert)
int absentIndex = fruits.IndexOf("Wassermelone"); // -1 (wenn nicht da)
Console.WriteLine(index);
Console.WriteLine(absentIndex);

Erstes passendes Element finden: Find

Du kannst auch nach einer Bedingung suchen, nicht nur nach einem Wert! Dafür gibt’s Find (oder den Index-Kumpel FindIndex):

// Finde die erste Frucht, deren Name länger als 4 Zeichen ist
string longFruit = fruits.Find(fruit => fruit.Length > 4); // "Apfel"
Console.WriteLine(longFruit);

Achtung: Wenn nichts gefunden wird, kommt der Standardwert für den Typ zurück (null bei Referenzen).

Mehrere Elemente finden: FindAll

Wenn du filtern willst (alle passenden), nimm FindAll:

// Alle Früchte, deren Name den Buchstaben 'i' enthält
List<string> withI = fruits.FindAll(f => f.Contains('i'));
foreach (var fruit in withI)
    Console.WriteLine(fruit); // "Kiwi"

3. Suche in Arrays: Methoden der Klasse Array

Arrays haben keine Find-Methode wie List<T>, aber dafür gibt’s die statische Klasse Array:

int[] numbers = { 1, 2, 3, 2, 4 };
int pos = Array.IndexOf(numbers, 2); // 1 — erster Index der 2
int lastPos = Array.LastIndexOf(numbers, 2); // 3 — letzter Index
Console.WriteLine(pos + ", " + lastPos);

Wenn du nach einer Bedingung suchen willst, geht das easy mit einer Schleife:

int firstGreaterThanTwo = -1;
for (int i = 0; i < numbers.Length; i++)
{
    if (numbers[i] > 2)
    {
        firstGreaterThanTwo = numbers[i];
        break;
    }
}
Console.WriteLine(firstGreaterThanTwo); // 3

4. Universelle Methoden für alle Kollektionen

Viele Kollektionen bieten Suchmethoden (Contains, IndexOf, Find usw.). Wenn du was Komplexeres brauchst, schreibst du einfach eine Schleife.

Beispiel: Prüfen, ob es eine Frucht gibt, die mit "B" anfängt

bool hasB = false;
foreach (var f in fruits)
{
    if (f.StartsWith("B"))
    {
        hasB = true;
        break;
    }
}
Console.WriteLine(hasB); // True

Beispiel: Erste Frucht finden, die "i" enthält

string withI = null;
foreach (var f in fruits)
{
    if (f.Contains('i'))
    {
        withI = f;
        break;
    }
}
Console.WriteLine(withI); // "Kiwi"

Beispiel: Suche nach eigenen Objekten

class Student
{
    public string Name;
    public int Group;
    public int Id;
}

List<Student> students = new List<Student>
{
    new Student { Name = "Ivan", Group = 101, Id = 1 },
    new Student { Name = "Maria", Group = 101, Id = 2 },
    new Student { Name = "Pjotr", Group = 102, Id = 3 },
};

// Suche Student mit Id == 2
Student maria = null;
foreach (var s in students)
{
    if (s.Id == 2)
    {
        maria = s;
        break;
    }
}
if (maria != null)
    Console.WriteLine(maria.Name); // "Maria"
else
    Console.WriteLine("Student nicht gefunden");

5. Suche in HashSet<T>: nur „Gibt’s das oder nicht?“

Sets (HashSet<T>) sind gemacht für schnelle „Gibt’s das?“-Abfragen. Sie bieten keine Suche nach Index, aber prüfen das Vorhandensein super schnell:

HashSet<int> set = new HashSet<int> { 1, 3, 5, 7 };
bool hasThree = set.Contains(3); // True
Console.WriteLine(hasThree);

// Wenn du nach einer Bedingung suchen willst (z.B. gibt’s gerade Zahlen?):
bool hasEven = false;
foreach (var x in set)
{
    if (x % 2 == 0)
    {
        hasEven = true;
        break;
    }
}
Console.WriteLine(hasEven); // False

6. Suche in Dictionaries: Dictionary<TKey, TValue>

Ein Dictionary ist eine Kollektion von „Schlüssel-Wert“-Paaren. Die Suche nach dem Schlüssel ist seine Superkraft.

Vorhandensein eines Schlüssels prüfen

Dictionary<int, string> idToName = new Dictionary<int, string>
{
    { 1, "Vasya" }, { 2, "Katja" }
};
if (idToName.ContainsKey(2))
    Console.WriteLine(idToName[2]); // "Katja"

Wert nach Schlüssel suchen: sicher!

if (idToName.TryGetValue(3, out string result))
    Console.WriteLine(result);
else
    Console.WriteLine("Kein Student mit dieser Id"); // Das wird ausgegeben

Suche nach Wert (selten und langsam):

bool containsVasya = idToName.ContainsValue("Vasya");
Console.WriteLine(containsVasya); // True

Eintrag nach Bedingung auf Wert oder Schlüssel finden

// Erster Id, wo der Name mit "K" anfängt
KeyValuePair<int, string> entry = default;
bool found = false;
foreach (var pair in idToName)
{
    if (pair.Value.StartsWith("K"))
    {
        entry = pair;
        found = true;
        break;
    }
}
if (found)
    Console.WriteLine($"{entry.Key}: {entry.Value}"); // "2: Katja"

7. Nützliche Details

Tabelle der Suchmethoden

Kollektionstyp Vorhandensein prüfen Contains Index finden IndexOf Nach Bedingung suchen Find Sichere Suche nach Schlüssel TryGetValue
List<T>
Ja Ja Ja (
Find
)
-
T[]
(Array)
Ja (
Array.Contains
/Schleife)
Ja (
Array.IndexOf
)
Schleife -
HashSet<T>
Ja - Nein (nur manuell) -
Dictionary<TKey,V>
Ja (
ContainsKey
)
- Manuell nach Schlüssel/Wert Ja

Iterative Suche: selbst schreiben

Für das volle Verständnis schreiben wir mal selbst eine Suchmethode für eine Kollektion. Zum Beispiel: Finde den Index des ersten Elements, das größer als ein bestimmter Wert ist:

static int FindFirstGreaterIndex(IEnumerable<int> collection, int minValue)
{
    int index = 0;
    foreach (var item in collection)
    {
        if (item > minValue)
            return index;
        index++;
    }
    return -1; // nicht gefunden
}

var nums = new List<int> { 1, 4, 7, 2 };
Console.WriteLine(FindFirstGreaterIndex(nums, 3)); // 1 (Zahl 4)

Hier sind wir nicht an einen Typ gebunden (List<T>, int[], sogar HashSet<T>), und auch nicht an die interne Umsetzung.

Suche in echten Aufgaben

  • Suche nach User per Login oder E-Mail in einer Datenbank.
  • Prüfen, ob ein bestimmtes Produkt im Warenkorb ist.
  • Schnelle Suche nach Einstellungen per Parametername.
  • Prüfen, ob ein bestimmter Schritt schon erledigt wurde (z.B. im Workflow).
  • Fehlerposition im Log-Array finden.

Bei fast jedem Vorstellungsgespräch für Mid-Level-Entwickler kommt die Frage: „Wie suchst du Elemente in einer Kollektion? Wie würdest du eine Methode schreiben, die das erste/alle/den Index eines Elements nach Bedingung zurückgibt?“ Also: Suchpraxis ist mega wichtig!

8. Typische Fehler und Besonderheiten bei der Suche

Wichtig: Suchmethoden hängen davon ab, wie Objekte verglichen werden. Wenn du eigene Klassen in eine Liste packst, ist der Standardvergleich ein Referenzvergleich! Damit die Suche „nach Inhalt“ klappt, musst du Equals und GetHashCode überschreiben (mehr dazu in den nächsten Vorlesungen).

Beispiel für ein Problem:

var s1 = new Student { Name = "Egor", Id = 42 };
students.Add(s1);
// Jetzt erstellen wir ein neues Objekt mit gleichem Id und Namen:
var s2 = new Student { Name = "Egor", Id = 42 };
Console.WriteLine(students.Contains(s2)); // False (!)

Der Compiler vergleicht nicht nach Feldern, sondern nach Referenz (das sind verschiedene Objekte).

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