З Swift 4 ви можете зробити це дуже легко. Є два нових ініціалізатори, які будують словник із послідовності кортежів (пар ключа і значення). Якщо ключі гарантовано унікальні, ви можете зробити наступне:
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 додає третій ініціалізатор, який групує елементи послідовності у словник. Ключі словника отримуються шляхом закриття. Елементи з однаковим ключем поміщаються в масив у тому самому порядку, що і в послідовності. Це дозволяє досягти подібних результатів, як зазначено вище. Наприклад:
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]]
? Якщо у вас двоє людей в однаковій позиції, ваш словник буде зберігати лише останнього, що зустрічався у вашому циклі .... У мене є подібне запитання, для якого я намагаюся знайти рішення, але я хочу, щоб результат був таким[1: [p1, p3], 2: [p2]]