List<>-Element mit Lambda-Ausdrücken bearbeiten

Das List<>-Element ist optimal um viele Objekte vom selben Typ im Programm-Code zu verarbeiten und zu verwalten. Dazu stellt es viele nützliche Funktionen bereit zum Sortieren, Durchsuchen. Meist ist man geneigt auf die Elemente mittels des Indexes zuzugreifen. Typischerweise in einer for oder foreach-Schleife und dann bestimmte Eigenschaften abzufragen.

Beispiel für List<>-Element zur weiteren Verwendung

Nehmen wir an, wir haben ein Objekt vom Typ Auto (Car):

class Car
{
    public string Carmaker;
    public string Type;
    public int Age;

    public Car(string carmaker, string type, int age)
    {
        Carmaker = carmaker;
        Type = type;
        Age = age;
    }
}

In einem anderen Programmteil erzeugen wir jetzt eine List<>-Element um die verschiedenen Auto-Objekte zu verwalten

public List<Car> listMyCars = new List<Car>();
listMyCars.Add(new Car("Audi", "Q5", 0));
listMyCars.Add(new Car("Porsche", "Cayenne", 5));
listMyCars.Add(new Car("Seat", "Leon", 2));
listMyCars.Add(new Car("VW", "Passat", 15));
listMyCars.Add(new Car("VW", "Golf", 7));
listMyCars.Add(new Car("BMW", "507", 70));

Liste konventionell durchlaufen

Muss man jetzt im Programmcode ein bestimmtes Objekt mit einer bestimmten Eigenschaft finden, würde man die List konventionell mit einer for- oder foreach-Schleife durchlaufen und die Eigenschaften prüfen. Im Beispiel suchen wir alle Autos vom Typ Passat:

foreach (Car c in listMyCars)
{
    if(c.Type == "Passat")
    {
        //do something
    }
}

List-Funktionen mit Lambda-Ausdrücken nutzen

Das ist viel Code zum Tippen und kann man mittels Lambda-Ausdrücken in den entsprechenden List-Funktionen eleganter lösen:

Finden eines Objekts in List<>

Mit der First()-Funktion können wir uns das erste Element einer Liste wiedergeben lassen, welches einer bestimmten Eigenschaft entspricht

Car myPassat = listMyCars.First(e => e.Carmaker == "VW");

Dieses Beispiel würde das Objekt Car("VW", "Passat", 15) zurückgeben. e => e.Carmaker == "VW" ist der zugehörige Lambda-Ausdruck für den Vergleich. So spart man sich mindestens 5 Zeilen Code. Dieselbe Funktion hat Find()

Car myPassat = listMyCars.Find(e => e.Carmaker == "VW");

Wenn es First() gibt muss es auch Last() geben, welches uns dann den Golf als Car-Objekt zurückliefert:

Car myPassat = listMyCars.Last(e => e.Carmaker == "VW");

FindIndex würde den Index zurückgeben vom Element in der List und hat noch verschiedene Überladungen.

int i = listMyCars.FindIndex(e => e.Carmaker == "VW");

Möchte man alle Objekte mit einer bestimmten Eigenschaft aus der Liste zurückgeliefert bekommen, kann man FindAll() benutzen

List<Car> listVWs = new List<Car>(5);
listVWs = listMyCars.FindAll(e => e.Carmaker == "VW");

Anstelle des Vergleiches auf Gleichheit können auch Vergleiche auf größer oder kleiner erfolgen, um z.B. alle Autos zu finden die älter als 7 Jahre sind

List<Car> listOldCars = new List<Car>(5);
listOldCars = listMyCars.FindAll(e => e.Age > 7);

Entfernen von Objekten aus List<>

Es können auch einfach Objekte mit bestimmten Eigenschaften aus einer Liste entfernt werden. Möchte man zum Beispiel alle Autos vom Hersteller VW aus unserer Liste entfernen, würde man schreiben:

listMyCars.RemoveAll(e => e.Carmaker == "VW");

Prüfen, ob ein List<>-Element mit bestimmter Eigenschaft existiert

Oft möchte man auch nur wissen, ob mindestens ein Objekt in der Liste existiert, welches eine bestimmte Eigenschaft hat. Die einfache Existenz kann man mit der Exist-Funktion überprüfen, z.B. ob ein Autotyp 507 in der Liste vorhanden ist.

if(listMyCars.Exists(e => e.Type == "507"))
{
    //do something
}

Mit der Any-Funktion prüft man, ob es irgendwelche Objekte in der Liste gibt, die der abgefragen Eigenschaft entsprechen. Zum Beispiel, ob es irgendwelche Autos mit dem Alter zwischen 5 und 10 Jahren gibt.

if(listMyCars.Any(e => (e.Age >= 5 && e.Age <=10)))
{
    //do something
}

Mit der All-Funktion prüft man, ob alle Objekte in der Liste eine bestimmte Eigenschaft aufweisen. Um z.B. herauszufinden, ob alle Autos in der Liste Gebrauchtwagen sind, könnte man folgende Abfrage starten, was in unserem Fall false zurückliefern würde, da es ein Auto mit dem Alter 0 in der Liste gibt.

if(listMyCars.All(e => (e.Age > 0))
{
    //do something
}

Die TrueForAll-Funktion prüft, ob alle Objekte in der Liste einer bestimmten Eigenschaft entsprechen. So kann man zum Beispiel Plausibilitätsprüfungen machen oder überprüfen, ob bestimmte Eigenschaften initiert sind (ungleich null). Die folgende Anweis prüft, ob das Alter aller Autos in der Liste größer/gleich null ist, also nicht negativ ist.

if(listMyCars.TrueForAll(e => (e.Age >= 0))
{
    //do something
}

Oder man prüft, ob zum Beispiel für alle Autos in der Liste der Hersteller angegeben ist

if(listMyCars.TrueForAll(e => (e.Carmaker != null))
{
    if(listMyCars.TrueForAll(e => (e.Carmaker.Trim() != ""))
    {
        //do something
    }
}

Mathematische Berechnungen über List-Elemente durchführen

Man kann auch ziemlich einfach sich den Durchschnitt oder die Summe über eine Liste ausrechnen lassen mit einer Codezeile.

Summe über List<>-Objekte bilden

Um die Summe über eine bestimmte Eigenschaft aller Objekte in einer Liste zu bilden, verwendet man die Sum-Funktion. In unserem Beispiel addieren hier das Alter aller Autos in der Liste.

int sum = listMyCars.Sum(e => e.Age);

Durchschnitt über List-Elemente bilden

Um einen Durchschnittswert über eine bestimmte Eigenschaft aller Objekte in einer Liste zu bilden, verwendet man die Average-Funktion. In unserem Beispiel ermitteln wir das Durchschnittsalter über alle Autos in der Liste.

double avg = listMyCars.Average(e => e.Age);

List<> durchlaufen aber Elemente ausschließen

Möchte man eine Liste durchlaufen, dabei aber Element mit bestimmten Eigenschaften ausschließen, kann man die SkipWhile-Funktion verwenden. Möchte man aus unserer Auto-Liste nur die Oldtimer verwenden, könnte man folgenden Code schreiben:

foreach (Car c in listMyCars.SkipWhile(e => e.Age < 50))
{
          //do something with oldtimer
}

Eine andere Variante ist die TakeWhile-Funktion. Dabei werden alle Elemente solange durchlaufen bis eine Objekt kommt, das der angegebenen Eigenschaft entspricht. Das folgende Beispiel würde nur die ersten drei Elemente unserer Liste (Audi, Porsche und SEAT) durchlaufen und dann abbrechen.

foreach (Car c in listMyCars.TakeWhile(e => e.Age < 15))
{
          //do something
}

Werbung



comments powered by Disqus

Copyright Dunkel & Iwer GbR | Datenschutzerklärung | Impressum