Menu
Coddy logo textTech

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.

challenge icon

Aufgabe

Mittel

Schreiben 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:

  1. matched: <...>
  2. 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,5

Spickzettel

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
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Logik & Kontrollfluss