Desde o Swift 4, você pode fazer isso facilmente. Existem dois novos inicializadores que constroem um dicionário a partir de uma sequência de tuplas (pares de chave e valor). Se as chaves forem exclusivas, você pode fazer o seguinte:
let persons = [Person(name: "Franz", position: 1),
Person(name: "Heinz", position: 2),
Person(name: "Hans", position: 3)]
Dictionary(uniqueKeysWithValues: persons.map { ($0.position, $0.name) })
=> [1: "Franz", 2: "Heinz", 3: "Hans"]
Isso falhará com um erro de tempo de execução se alguma chave for duplicada. Nesse caso, você pode usar esta versão:
let persons = [Person(name: "Franz", position: 1),
Person(name: "Heinz", position: 2),
Person(name: "Hans", position: 1)]
Dictionary(persons.map { ($0.position, $0.name) }) { _, last in last }
=> [1: "Hans", 2: "Heinz"]
Isso se comporta como seu loop for. Se você não quiser "sobrescrever" valores e se ater ao primeiro mapeamento, pode usar isto:
Dictionary(persons.map { ($0.position, $0.name) }) { first, _ in first }
=> [1: "Franz", 2: "Heinz"]
O Swift 4.2 adiciona um terceiro inicializador que agrupa os elementos da sequência em um dicionário. As chaves do dicionário são derivadas de um encerramento. Elementos com a mesma chave são colocados em uma matriz na mesma ordem que na sequência. Isso permite que você obtenha resultados semelhantes aos acima. Por exemplo:
Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.last! }
=> [1: Person(name: "Hans", position: 1), 2: Person(name: "Heinz", position: 2)]
Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.first! }
=> [1: Person(name: "Franz", position: 1), 2: Person(name: "Heinz", position: 2)]
[position:name]
ou[position:[name]]
? Se você tiver duas pessoas na mesma posição, seu dicionário manterá apenas a última encontrada em seu loop ... Tenho uma pergunta semelhante para a qual estou tentando encontrar uma solução, mas quero que o resultado seja como[1: [p1, p3], 2: [p2]]