Swift 4以降、これは非常に簡単に実行できます。あり2つの 新しいタプル(キーと値のペア)の配列から辞書を構築する初期化子が。キーが一意であることが保証されている場合は、次の操作を実行できます。
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"]
キーが重複している場合、これはランタイムエラーで失敗します。その場合、このバージョンを使用できます。
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"]
これはforループとして動作します。値を「上書き」して最初のマッピングに固執したくない場合は、次のように使用できます。
Dictionary(persons.map { ($0.position, $0.name) }) { first, _ in first }
=> [1: "Franz", 2: "Heinz"]
Swift 4.2は、シーケンス要素を辞書にグループ化する3番目の初期化子を追加します。辞書キーはクロージャによって派生します。同じキーを持つ要素は、シーケンスと同じ順序で配列に配置されます。これにより、上記と同様の結果を得ることができます。例えば:
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]
またはの辞書が必要[position:[name]]
ですか?同じ位置に2人いる場合、辞書はループ内で最後に遭遇したものだけを保持します....解決策を見つけようとしている同様の質問がありますが、結果は次のようになります。[1: [p1, p3], 2: [p2]]