Eigene Higher-Order
Teil des Abschnitts Logik & Kontrollfluss der Swift-Journey von Coddy — Lektion 42 von 56.
Jetzt können Sie Ihre eigenen Funktionen höherer Ordnung schreiben, und sie fügen sich nahtlos neben map und filter ein. Das Schema ist immer dasselbe: einen Closure-Parameter entgegennehmen, ihn innerhalb der Schleife aufrufen und das Ergebnis zurückgeben.
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]Wenn sich Extensions nach zu viel anfühlen, schreibe stattdessen eine freie Funktion; die Idee ist dieselbe:
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Sobald man Closures übergeben kann, hört die Standardbibliothek auf, wie Magie auszusehen, und fängt an, wie eine Reihe von Mustern auszusehen, die man selbst schreiben könnte.
Aufgabe
MittelSchreiben Sie eine freie Funktion partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]), die das Array einmal durchläuft und ein Tupel (matched, rest) zurückgibt: Elemente, die das Prädikat erfüllt haben, und den Rest, beide in der ursprünglichen Reihenfolge.
Lesen Sie zwei Zeilen ein: eine Ganzzahl min, dann eine durch Kommas getrennte Liste von Ganzzahlen. Verwenden Sie Ihre partition-Funktion mit einem Prädikat, das n > min prüft. Geben Sie Folgendes aus:
matched: <...>rest: <...>
Jede Liste wird mit , zusammengefügt (oder bleibt leer, wenn nichts auszugeben ist).
Für die Eingabe 5 / 2,7,3,8,5 lautet die Ausgabe:
matched: 7,8
rest: 2,3,5Spickzettel
Funktionen höherer Ordnung folgen einem konsistenten Muster: einen Closure akzeptieren, ihn in einer Schleife aufrufen, das Ergebnis zurückgeben.
Als Erweiterung:
extension Array {
func myMap<T>(_ transform: (Element) -> T) -> [T] {
var result: [T] = []
for item in self {
result.append(transform(item))
}
return result
}
}
[1, 2, 3].myMap { $0 * 10 } // [10, 20, 30]Als freie Funktion:
func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
var n = 0
for item in items where predicate(item) {
n += 1
}
return n
}Eine partition-Funktion, die ein Tuple aus übereinstimmenden und nicht übereinstimmenden Elementen zurückgibt:
func partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) {
var matched: [Int] = []
var rest: [Int] = []
for item in items {
if predicate(item) { matched.append(item) }
else { rest.append(item) }
}
return (matched, rest)
}Probier es selbst
let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: partition(_:by:) -> ([Int], [Int]); Übereinstimmungen und Rest ausgeben
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Kontrollfluss
1Strings im Detail
Zählen und IndizesGroß-/Kleinschreibung und TrimmenSuchen in StringsTeilen und ZusammenfügenTeilstrings ersetzenWiederholung – Benutzernamen-Check4Mengen
Mengen erstellenVereinigung und SchnittmengeDifferenz und symmetrische DifferenzTeilmenge und ObermengeRückblick – Tag-Filter7Projekt - Habit Tracker
ProjektübersichtAls erledigt markieren2Bereiche & Schrittweiten
Geschlossen vs. halboffenSchrittweiteRange-MethodenRanges in SwitchRückblick – Kalender-Grid5Funktionen höherer Ordnung Teil 1
MapFilterReduceVerkettung von map, filter, reduceRückblick – Wortstatistiken8Closures
Closure-GrundlagenTrailing ClosuresWerte erfassenClosures zurückgebenEigene Higher-OrderRückblick – Pipeline Builder