Uso de KeyPaths em Coleções
Ordene e transforme coleções por caminho de chave.
Uso de KeyPaths em Coleções é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
O poder dos caminhos de chave nas coleções
Operações de coleção como map, sorted e filter geralmente apenas leem uma propriedade de cada elemento. Os caminhos de chave permitem expressar essa intenção sem escrever um fechamento.
Swift aceita um caminho de chave em qualquer lugar onde se espera uma função de um único argumento que retorne um valor, pois um caminho de chave pode ser usado como uma função de Root para 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)map com a forma abreviada de caminho de chave
Passar map(\.property) equivale a escrever um fechamento que retorna essa propriedade, mas é mais curto e claro. A barra invertida e o ponto iniciais permitem que o compilador deduza o tipo do elemento.
Compare as duas formas abaixo; elas produzem o mesmo resultado.
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:) com uma comparação por caminho de chave
Para ordenar por uma propriedade, você ainda escreve um pequeno fechamento de comparação, mas pode ler a propriedade por meio de um caminho de chave dentro dele para tornar o código mais claro.
Aqui ordenamos as pessoas da mais jovem para a mais velha comparando seus valores de 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))Uma função auxiliar reutilizável para ordenação
Você pode escrever uma função auxiliar genérica que ordena qualquer matriz por qualquer propriedade comparável, recebendo a propriedade como um argumento de caminho de chave. Assim, ordenar por um campo se transforma em uma única linha em todo o seu código.
A restrição T: Comparable garante que a propriedade possa ser ordenada.
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))Filtrando por meio de um caminho de chave
Para filter, você precisa de um predicado que retorne um booleano, portanto um caminho de chave de propriedade simples só funciona diretamente quando a propriedade já é um booleano.
Aqui cada tarefa tem um sinalizador isDone, e filtramos por ele usando a forma abreviada de caminho de chave.
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))Filtrando por uma propriedade não booleana
Ao filtrar por uma propriedade não booleana, leia-a por meio de um caminho de chave dentro de um fechamento e faça uma comparação. Uma função auxiliar genérica pode encapsular esse padrão para qualquer propriedade equacionável.
Aqui mantemos apenas as pessoas cuja cidade corresponde a um destino.
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 e min por caminho de chave
Os métodos max(by:) e min(by:) recebem um fechamento de comparação, assim como sorted. Leia a propriedade por meio de um caminho de chave para encontrar o elemento com o maior ou o menor valor.
Aqui encontramos a pessoa mais velha.
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)
}Somando uma propriedade com reduce
Você pode combinar map(\.property) com reduce para totalizar um campo numérico. Primeiro, projete cada elemento para o número desejado e depois some todos eles.
Aqui somamos todas as idades em um único fluxo.
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)Agrupando por um caminho de chave
Dictionary(grouping:by:) agrupa elementos de acordo com o resultado de um fechamento. Leia uma propriedade por meio de um caminho de chave para agrupar por esse campo.
Aqui as pessoas são agrupadas por cidade em um dicionário de matrizes.
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) ?? [])Ordenação por vários campos
Para ordenar por um campo e resolver empates usando outro, compare primeiro o caminho de chave principal e use o secundário quando os valores principais forem iguais.
Aqui ordenamos por idade e depois por nome quando as idades são iguais.
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))Por que os caminhos de chave superam os fechamentos aqui
Usar caminhos de chave em chamadas de coleções reduz o código repetitivo, elimina a possibilidade de um erro de digitação no corpo do fechamento e torna a intenção evidente: você está projetando um único campo.
Para transformações complexas, um fechamento ainda é a ferramenta certa, mas, para uma simples leitura de propriedade, \.property é a escolha mais clara.
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)Verificação rápida: caminho de chave em map
Escolha a forma abreviada de caminho de chave para extrair uma propriedade de cada elemento.
Recapitulação: caminhos de chave nas coleções
Você viu como os caminhos de chave tornam o código de coleções mais conciso:
map(\.property)projeta um único campo sem um fechamento.filter(\.boolProperty)funciona diretamente para campos booleanos; para os demais, use um fechamento com[keyPath:].- A ordenação,
maxeminleem a propriedade por meio de um caminho de chave dentro de seus fechamentos de comparação. - Funções auxiliares genéricas que recebem um
KeyPathtransformam a ordenação e a filtragem por um campo em operações reutilizáveis de uma única linha.
A seguir, você aprenderá sobre caminhos de chave graváveis, que permitem definir valores, não apenas lê-los.
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))Aprenda Swift com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 122
- Aulas
- 409
Perguntas Frequentes
A aula “Uso de KeyPaths em Coleções” é grátis?
Sim — o texto completo de “Uso de KeyPaths em Coleções” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “Uso de KeyPaths em Coleções”?
Ordene e transforme coleções por caminho de chave. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Uso de KeyPaths em Coleções”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Noções Básicas de KeyPath
- Uso de KeyPaths em Coleções
- KeyPaths Graváveis e de Referência
- @dynamicMemberLookup