0Pricing
Swift Academy · Lektion

KeyPaths in Collections verwenden

Sortieren und transformieren Sie Collections anhand eines KeyPaths.

KeyPaths in Collections verwenden ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.

Key Paths in Collections im Einsatz

Collection-Operationen wie map, sorted und filter lesen häufig einfach nur eine Eigenschaft jedes Elements. Mit Key Paths können Sie diese Absicht ausdrücken, ohne eine Closure zu schreiben.

Swift akzeptiert einen Key Path überall dort, wo eine Funktion mit einem Argument erwartet wird, die einen Wert zurückgibt, da ein Key Path als Funktion von Root nach Value verwendet werden kann.

struct Person {
    let name: String
    let age: Int
}

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let names = people.map(\.name)
print(names)

map mit der Kurzschreibweise für Key Paths

Die Übergabe von map(\.property) entspricht dem Schreiben einer Closure, die diese Eigenschaft zurückgibt, ist aber kürzer und verständlicher. Der führende Backslash und Punkt ermöglichen es dem Compiler, den Elementtyp abzuleiten.

Vergleichen Sie die beiden folgenden Formen: Sie liefern dasselbe Ergebnis.

struct Person {
    let name: String
    let age: Int
}

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let closureForm = people.map { $0.age }
let keyPathForm = people.map(\.age)
print(closureForm)
print(keyPathForm)

sorted(by:) mit einem Key-Path-Vergleich

Um nach einer Eigenschaft zu sortieren, schreiben Sie weiterhin eine kleine Vergleichs-Closure. Innerhalb dieser Closure können Sie die Eigenschaft jedoch über einen Key Path lesen, was die Übersichtlichkeit erhöht.

Hier sortieren wir Personen vom jüngsten zum ältesten Alter, indem wir ihre age-Werte vergleichen.

struct Person {
    let name: String
    let age: Int
}

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let path = \Person.age
let sorted = people.sorted { $0[keyPath: path] < $1[keyPath: path] }
print(sorted.map(\.name))

Ein wiederverwendbarer Sortierhelfer

Sie können einen generischen Helfer schreiben, der jedes Array nach einer beliebigen vergleichbaren Eigenschaft sortiert und die Eigenschaft als Key-Path-Argument entgegennimmt. Dadurch wird das Sortieren nach einem Feld in Ihrer gesamten Codebasis zu einer einzigen Zeile.

Die Einschränkung T: Comparable stellt sicher, dass die Eigenschaft geordnet werden kann.

func sorted<E, T: Comparable>(_ array: [E], by path: KeyPath<E, T>) -> [E] {
    array.sorted { $0[keyPath: path] < $1[keyPath: path] }
}

struct Person { let name: String; let age: Int }
let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
print(sorted(people, by: \.age).map(\.name))

Filtern über einen Key Path

Für filter benötigen Sie ein Prädikat, das einen Bool-Wert zurückgibt. Daher funktioniert ein einfacher Eigenschafts-Key-Path nur dann direkt, wenn die Eigenschaft bereits ein Bool-Wert ist.

Hier besitzt jede Aufgabe ein isDone-Flag, nach dem wir mithilfe der Kurzschreibweise für Key Paths filtern.

struct Task {
    let title: String
    let isDone: Bool
}

let tasks = [Task(title: "A", isDone: true), Task(title: "B", isDone: false)]
let finished = tasks.filter(\.isDone)
print(finished.map(\.title))

Filtern nach einer Nicht-Bool-Eigenschaft

Wenn Sie nach einer Nicht-Bool-Eigenschaft filtern, lesen Sie sie innerhalb einer Closure über einen Key Path und vergleichen sie dort. Ein generischer Helfer kann dieses Muster für jede vergleichbare Eigenschaft kapseln.

Hier behalten wir nur die Personen, deren Stadt mit einem Zielwert übereinstimmt.

struct Person { let name: String; let city: String }

func filter<E, T: Equatable>(_ array: [E], _ path: KeyPath<E, T>, equals value: T) -> [E] {
    array.filter { $0[keyPath: path] == value }
}

let people = [Person(name: "Ana", city: "Oslo"), Person(name: "Ben", city: "Rome")]
print(filter(people, \.city, equals: "Oslo").map(\.name))

max und min nach einem Key Path

Die Methoden max(by:) und min(by:) erwarten wie sorted eine Vergleichs-Closure. Lesen Sie die Eigenschaft über einen Key Path, um das Element mit dem größten oder kleinsten Wert zu finden.

Hier ermitteln wir die älteste Person.

struct Person { let name: String; let age: Int }

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25), Person(name: "Cy", age: 41)]
let path = \Person.age
if let oldest = people.max(by: { $0[keyPath: path] < $1[keyPath: path] }) {
    print(oldest.name)
}

Eine Eigenschaft mit reduce summieren

Sie können map(\.property) mit reduce kombinieren, um ein numerisches Feld zu summieren. Projizieren Sie zunächst jedes Element auf die gewünschte Zahl und addieren Sie anschließend alle Werte.

Hier summieren wir alle Altersangaben in einer einzigen Pipeline.

struct Person { let name: String; let age: Int }

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let totalAge = people.map(\.age).reduce(0, +)
print(totalAge)

Gruppieren nach einem Key Path

Dictionary(grouping:by:) ordnet Elemente anhand des Ergebnisses einer Closure Gruppen zu. Lesen Sie eine Eigenschaft über einen Key Path, um nach diesem Feld zu gruppieren.

Hier werden Personen nach ihrer Stadt in einem Dictionary aus Arrays gruppiert.

struct Person { let name: String; let city: String }

let people = [
    Person(name: "Ana", city: "Oslo"),
    Person(name: "Ben", city: "Rome"),
    Person(name: "Cy", city: "Oslo")
]
let path = \Person.city
let byCity = Dictionary(grouping: people, by: { $0[keyPath: path] })
print(byCity["Oslo"]?.map(\.name) ?? [])

Sortieren nach mehreren Feldern

Um zunächst nach einem Feld zu sortieren und Gleichstände anhand eines weiteren Feldes aufzulösen, vergleichen Sie zuerst den primären Key Path und greifen nur bei gleichen primären Werten auf den sekundären zurück.

Hier sortieren wir nach dem Alter und bei gleichem Alter zusätzlich nach dem Namen.

struct Person { let name: String; let age: Int }

let people = [
    Person(name: "Zoe", age: 30),
    Person(name: "Ana", age: 30),
    Person(name: "Ben", age: 25)
]
let sorted = people.sorted {
    if $0[keyPath: \Person.age] != $1[keyPath: \Person.age] {
        return $0.age < $1.age
    }
    return $0.name < $1.name
}
print(sorted.map(\.name))

Warum Key Paths hier besser sind als Closures

Die Verwendung von Key Paths in Collection-Aufrufen reduziert überflüssigen Code, vermeidet Tippfehler im Rumpf der Closure und macht die Absicht deutlich: Sie projizieren ein einzelnes Feld.

Für komplexe Umformungen ist eine Closure weiterhin das richtige Werkzeug. Für das einfache Lesen einer Eigenschaft ist \.property jedoch die klarste Wahl.

struct Product { let name: String; let price: Double }

let products = [Product(name: "Pen", price: 2), Product(name: "Pad", price: 5)]
let names = products.map(\.name)
let prices = products.map(\.price)
print(names)
print(prices)

Kurzer Test: Key Path in map

Wählen Sie die knappe Form mit einem Key Path, um eine Eigenschaft aus jedem Element zu extrahieren.

Zusammenfassung: Key Paths in Collections

Sie haben gesehen, wie Key Paths Collection-Code kompakter machen:

  • map(\.property) projiziert ein einzelnes Feld ohne Closure.
  • filter(\.boolProperty) funktioniert direkt für Bool-Felder; für andere Felder verwenden Sie eine Closure mit [keyPath:].
  • Beim Sortieren sowie bei max und min wird die Eigenschaft innerhalb der Vergleichs-Closures über einen Key Path gelesen.
  • Generische Helfer, die einen KeyPath entgegennehmen, machen das Sortieren und Filtern nach einem Feld zu wiederverwendbaren Einzeilern.

Als Nächstes lernen Sie schreibbare Key Paths kennen, mit denen Sie Werte nicht nur lesen, sondern auch setzen können.

struct Person { let name: String; let age: Int }

let people = [Person(name: "Ana", age: 30), Person(name: "Ben", age: 25)]
let youngestFirst = people.sorted { $0[keyPath: \Person.age] < $1[keyPath: \Person.age] }
print(youngestFirst.map(\.name))

Häufig gestellte Fragen

Ist die Lektion „KeyPaths in Collections verwenden“ kostenlos?

Ja — der vollständige Text von „KeyPaths in Collections verwenden“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „KeyPaths in Collections verwenden“?

Sortieren und transformieren Sie Collections anhand eines KeyPaths. Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Swift Academy zu starten?

Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „KeyPaths in Collections verwenden“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?

Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen von KeyPaths
  2. KeyPaths in Collections verwenden
  3. Schreibbare und Referenz-KeyPaths
  4. @dynamicMemberLookup
← Zurück zu Swift Academy