Swift Academy · Leçon

Utiliser KeyPaths dans les collections

Triez et transformez des collections selon un chemin de clé.

Leçon 2 sur 413 étapes

Utiliser KeyPaths dans les collections est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.

Les chemins de clés s'illustrent dans les collections

Les opérations sur les collections telles que map, sorted et filter se contentent souvent de lire une propriété de chaque élément. Les chemins de clés vous permettent d'exprimer cette intention sans écrire de fermeture.

Swift accepte un chemin de clé partout où une fonction à un seul argument qui renvoie une donnée est attendue, car un chemin de clé peut être utilisé comme une fonction allant de Root à Value.

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)

Notation abrégée de map avec un chemin de clé

Passer map(\.property) revient à écrire une fermeture qui renvoie cette propriété, mais en plus court et plus clair. La barre oblique inverse et le point initiaux permettent au compilateur d'inférer le type des éléments.

Comparez les deux formes ci-dessous : elles produisent le même résultat.

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:) avec une comparaison fondée sur un chemin de clé

Pour trier selon une propriété, vous écrivez toujours une petite fermeture de comparaison, mais vous pouvez lire la propriété au moyen d'un chemin de clé à l'intérieur, pour plus de clarté.

Ici, nous trions les personnes de la plus jeune à la plus âgée en comparant leurs valeurs age.

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))

Un outil réutilisable pour le tri

Vous pouvez écrire une fonction générique qui trie n'importe quel tableau selon n'importe quelle propriété comparable, en prenant la propriété comme argument de type chemin de clé. Le tri selon un champ tient ainsi en une seule ligne dans toute votre base de code.

La contrainte T: Comparable garantit que la propriété peut être ordonnée.

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))

Filtrer au moyen d'un chemin de clé

Pour filter, vous avez besoin d'un prédicat qui renvoie un Bool ; un simple chemin de clé de propriété ne fonctionne donc directement que lorsque la propriété est déjà un Bool.

Ici, chaque tâche possède un indicateur isDone, et nous filtrons dessus à l'aide de la notation abrégée des chemins de clés.

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))

Filtrer selon une propriété qui n'est pas un Bool

Lorsque vous filtrez selon une propriété qui n'est pas un Bool, lisez-la au moyen d'un chemin de clé à l'intérieur d'une fermeture, puis comparez-la. Une fonction générique peut reprendre ce schéma pour toute propriété comparable par égalité.

Ici, nous conservons uniquement les personnes dont la propriété city correspond à une cible.

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 et minimum selon un chemin de clé

Les méthodes max(by:) et min(by:) prennent une fermeture de comparaison, tout comme sorted. Lisez la propriété au moyen d'un chemin de clé pour trouver l'élément dont la valeur est la plus grande ou la plus petite.

Ici, nous trouvons la personne la plus âgée.

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)
}

Additionner une propriété avec reduce

Vous pouvez combiner map(\.property) avec reduce pour totaliser un champ numérique. Commencez par projeter chaque élément sur le nombre souhaité, puis additionnez-les.

Ici, nous additionnons tous les âges dans une seule chaîne de traitement.

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)

Regrouper selon un chemin de clé

Dictionary(grouping:by:) répartit les éléments en groupes selon le résultat d'une fermeture. Lisez une propriété au moyen d'un chemin de clé pour regrouper selon ce champ.

Ici, les personnes sont regroupées selon city dans un dictionnaire de tableaux.

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) ?? [])

Tri selon plusieurs champs

Pour trier selon un champ et départager les égalités avec un autre, comparez d'abord le chemin de clé principal, puis utilisez le chemin secondaire lorsque les clés principales sont égales.

Ici, nous trions d'abord selon la propriété age, puis selon le nom pour les âges identiques.

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))

Pourquoi les chemins de clés sont préférables aux fermetures ici

L'utilisation de chemins de clés dans les appels sur les collections réduit le code répétitif, élimine le risque de faute de frappe dans le corps de la fermeture et rend l'intention évidente : vous projetez un seul champ.

Pour les transformations complexes, une fermeture reste l'outil adapté, mais pour une simple lecture de propriété, \.property est le choix le plus clair.

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)

Vérification rapide : chemin de clé dans map

Choisissez la forme concise avec un chemin de clé pour extraire une propriété de chaque élément.

Récapitulatif : chemins de clés dans les collections

Vous avez vu comment les chemins de clés rendent le code des collections plus concis :

  • map(\.property) projette un seul champ sans fermeture.
  • filter(\.boolProperty) fonctionne directement pour les champs Bool ; pour les autres, utilisez une fermeture avec [keyPath:].
  • Le tri, max et min lisent la propriété au moyen d'un chemin de clé à l'intérieur de leurs fermetures de comparaison.
  • Les fonctions génériques qui acceptent un KeyPath transforment le tri et le filtrage selon un champ en opérations réutilisables d'une seule ligne.

Vous allez maintenant découvrir les chemins de clés accessibles en écriture, qui permettent de définir des valeurs et pas seulement de les lire.

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))
Gratuit pour commencer

Apprends Swift avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
122
Leçons
409

Questions Fréquemment Posées

La leçon « Utiliser KeyPaths dans les collections » est-elle gratuite ?

Oui — le texte complet de « Utiliser KeyPaths dans les collections » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Utiliser KeyPaths dans les collections » ?

Triez et transformez des collections selon un chemin de clé. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Swift Academy ?

Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Utiliser KeyPaths dans les collections » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?

Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Bases de KeyPath
  2. Utiliser KeyPaths dans les collections
  3. KeyPaths accessibles en écriture et de référence
  4. @dynamicMemberLookup
← Retour à Swift Academy