Operationen auf Listen ausführen
Wenn Sie in einer Liste viele Elemente gespeichert haben, führen Sie Vorgänge häufig entweder für die gesamte Liste oder für einen Teil der Liste aus. Das Listenmodul enthält genau hierfür zahlreiche nützliche Vorgänge.
Funktionen des Listenmoduls
Neben den Eigenschaften gibt es ein Listenmodul mit Funktionen, die für eine Liste ausgeführt werden können. Mit den Funktionen werden häufig verwendete Vorgänge ausgeführt, wie z. B. Suchen, Filtern, Sortieren, Ausführen mathematischer Operationen usw.
Wiederholung
Bei einer Iteration wird jedes Element einer Liste von einem Anfangs- bis zu einem Endpunkt durchlaufen. Für Iterationen sind zwei Funktionen besonders nützlich:
iter(): Mit dieser Funktion können Sie über jedes Element in einer Liste iterieren, wie hier gezeigt:let cards = [ 1 .. 5 ] List.iter(fun i -> printfn "%i" i) cards // 1 2 3 4 5Die Funktion
iter()akzeptiert eine Funktion. Im vorherigen Code stellen Sie eine anonyme Funktion mithilfe des Schlüsselwortsfunbereit. Diese Funktion akzeptiert einen Parameter, der das aktuelle Element während des Durchlaufs darstellt. Der folgende Code ist das Äquivalent dazu, den folgenden Code mit einer Schleife zu schreiben:for i in cards do printfn "%i" imap(): Diese Funktion ähneltiter(), ermöglicht Ihnen jedoch, das Vorhandene zu transformieren. Hier sehen Sie ein Beispiel:type Person = { FirstName: string; LastName: string } let people = [ { FirstName="Albert"; LastName= "Einstein" } { FirstName="Marie"; LastName="Curie" } ] let nobelPrizeWinners = List.map (fun person -> person.FirstName + person.LastName) people printfn "%A" nobelPrizeWinners // ["Albert Einstein"; "Marie Curie"]Im vorherigen Code wird die Liste von
Person-Objekten in eine Liste von Zeichenfolgen transformiert.
Filtern
Auch die Funktion filter() akzeptiert eine Funktion als Parameter, ihr Zweck besteht jedoch darin, die Elemente zu definieren, die beibehalten werden sollen. Ergibt der Ausdruck true, wird das Element beibehalten. Ergibt der Ausdruck false, wird das Element nicht in der gefilterten Liste angezeigt. Im folgenden Beispiel wird eine Liste so gefiltert, dass nur Elemente, deren Wert durch zwei teilbar ist, beibehalten werden:
let cards = [ 1 .. 5 ]
let filteredList = List.filter(fun i-> i % 2 = 0) cards
List.iter(fun i -> printfn "item %i" i) filteredList // item 2 item 4
Die Liste filteredList enthält jetzt nur die Elemente, die nach der Auswertung durch true den Wert i % 2 = 0 zurückgeben (das sind 2 und 4).
Sortieren
Das Sortieren einer Liste ist eine häufig durchgeführte Aktion. Die folgenden drei Funktionen können für das Sortieren von Listen nützlich sein:
sort()sortiert in aufsteigender Reihenfolge. Hier sehen Sie ein Beispiel:let list = [2; 1; 5; 3] let sortedList = List.sort list // 1 2 3 5sortBy(): Mit dieser Funktion wird auf einen Schlüssel verwiesen, nach dem sortiert werden soll. Angenommen, Sie verfügen über eine Liste von Personen, und jeder Eintrag weist die Feldernameundageauf. Hier können Sie beispielsweise nachagesortieren. Diese Funktion nimmt eine Funktion an, in der Sie auf den Schlüssel verweisen. Ein weiterer Schlüssel kann die Länge einer Zeichenfolge sein, wie in dem folgenden Beispiel:let fruits = ["Banana"; "Apple"; "Pineapple"] let sortedFruits = List.sortBy (fun (fruit : string) -> fruit.Length) fruits // Apple, Banana, PineapplesortWith(): Mit dieser Funktion können Sie eine Vergleichsfunktion bereitstellen, da möglicherweise nicht sofort ersichtlich ist, welches der Elemente zuerst sortiert werden sollte. Der folgende Code enthält ein Beispiel hierzu:// assume a type like so type MagicCreature = { Name : string; Level: int; Attack: int } let creatures = [ { Name="Dragon"; Level=2; Attack=20 } { Name="Orc"; Level=1; Attack=5 } { Name="Demon"; Level=2; Attack=10 } ] // comparison function, -1 = less than, 1 = larger than, 0 = equal let compareCreatures c1 c2 = if c1.Level < c2.Level then -1 else if c1.Level > c2.Level then 1 else if c1.Attack < c2.Attack then -1 else if c1.Attack > c2.Attack then 1 else 0 let sorted = List.sortWith compareCreatures creatures // { Name="Orc"; Level=1; Attack=5 }, { Name="Demon"; Level=2; Attack=10 }, { Name="Dragon"; Level=2; Attack=20 }Die vorherige Vergleichsfunktion
compareCreatures()versucht zunächst, nachLevelzu vergleichen. Bei gleicher Ebene versucht sie, nachAttackzu vergleichen. Bei einem Rückgabewert von-1ist der Wert kleiner, bei1größer und bei0gleich groß.
Suchen
Eine weitere Möglichkeit besteht darin, ein bestimmtes Element zu suchen. Die folgenden Funktionen stehen hierfür zur Auswahl:
find(): Diese Funktion sucht das erste Element, das eine bestimmte Bedingung erfüllt. Für die Nutzung vonfind()müssen Sie auch eine Funktion (Prädikat) bereitstellen, die ausdrückt, wie das Element gesucht werden soll. Hier sehen Sie ein Beispiel:let list = [1; 2; 3; 4] let found = List.find( fun x -> x % 2 = 0) list // 2 - Only the first element that matches the condition is returned.tryFind(). Diese Funktion nimmt eine Funktion (Prädikat), die angibt, wie der Wert gefunden wird, und eine Liste, in der gesucht werden soll. Sie gibt eine Option zurück. Hier sehen Sie ein Beispiel zur Verwendung:let findValue aValue aList = let found = aList |> List.tryFind(fun item -> item = aValue) match found with | Some value -> printfn "%i" value | None -> printfn "Not found" findValue 1 list // 1 findValue 5 list // Not foundIm vorherigen Code senden Sie einen Wert, der mit der Liste verglichen werden soll. Wenn er gefunden wird, gibt er
Somezurück. Wird der Wert nicht gefunden, lautet die RückgabeNone.tryFindIndex(). Wie beitryFind()gibt diese Funktion eine Option zurück und akzeptiert eine Funktion (Prädikat), die einen booleschen Wert ergibt. Der Code könnte etwa folgendermaßen aussehen:let found = List.tryFindIndex(fun x -> x = 4) list match found with | Some index -> printfn "%i" index | None -> printfn "Not found"
Arithmetische Operationen
In manchen Situationen kann es nützlich sein, für eine Liste mathematische Operationen auszuführen. Die folgenden drei Funktionen sind von den zahlreichen Funktionen, die in der Listen-API zur Verfügung stehen, am nützlichsten:
sum(): Mit dieser Funktion durchlaufen Sie jedes Element, um alle Werte in der Liste zu summieren. Hier sehen Sie ein Beispiel zur Verwendung:let sum = List.sum [1 .. 5] // sum = 15sumBy(): Mit dieser Funktion geben Sie an, wie die Werte summiert werden sollen. Eine Möglichkeit besteht darin, auf die Felder zu verweisen, die summiert werden sollen:type OrderItem = { Name: string; Cost:int } let orderItems = [ { Name="XBox"; Cost=500 } { Name="Book"; Cost=10 } { Name="Movie ticket"; Cost=7 } ] let sum = List.sumBy(fun item -> item.Cost) orderItems printfn "%i" sum // 517Im vorherigen Code wird auf das Feld
Costverwiesen, wodurch jedes Element in diesem Feld der Summe hinzugefügt wird.average(): Diese Funktion ähneltsum()darin, dass sie mit einer Liste von Zahlen arbeitet. Doch es gibt zwei Unterschiede:- Sie erwartet als Daten Gleitkommazahlen, keine ganzen Zahlen.
- Sie berechnet einen Durchschnittswert, keine Summe.
Hier sehen Sie ein Beispiel:
let numbers = [ 1.0; 2.5; 3.0 ] let avg = List.average numbers printfn "%f" avg // 2.166667averageBy(): Wie beisumBy()akzeptiertaverageBy()eine Funktion, in der Sie den gewünschten Wert angeben. Hier sehen Sie ein Beispiel:type WeatherMeasurement = { Date: string; Temperature: float } let measurements = [ { Date="07/20/2021"; Temperature=21.3 } { Date="07/21/2021"; Temperature=23.2 } { Date="07/22/2021"; Temperature=20.7 } ] let avgBy = List.averageBy(fun m -> m.Temperature) measurements printfn "%f" avgBy // 21.733333