Как создать словарь из массива кортежей?
Давайте скажем, что у меня есть массив объектов, которые можно идентифицировать, и я хочу создать словарь из него. Я легко могу получить кортежи из своего массива следующим образом:
let tuples = myArray.map { return ($0.id, $0) }
Но я не вижу инициализатора для словаря, чтобы взять массив кортежей. Я что-то упускаю? У меня есть расширение для словаря для этой функции (на самом деле это не сложно, но я думал, что он будет предоставлен по умолчанию), или есть более простой способ сделать это?
Существует код для расширения
extension Dictionary
{
public init (_ arrayOfTuples : Array<(Key, Value)>)
{
self.init(minimumCapacity: arrayOfTuples.count)
for tuple in arrayOfTuples
{
self[tuple.0] = tuple.1
}
}
}
Ответы
Ответ 1
Swift 4
Если ваш кортеж (Hashable, String) вы можете использовать:
let array = [("key1", "value1"), ("key2", "value2"), ("key3", "value3")]
let dictionary = array.reduce(into: [:]) { $0[$1.0] = $1.1 }
print(dictionary) // ["key1": "value1", "key2": "value2", "key3": "value3"]
Ответ 2
В зависимости от того, что вы хотите сделать, вы можете:
let tuples = [(0, "0"), (1, "1"), (1, "2")]
var dictionary = [Int: String]()
Вариант 1: заменить существующие ключи
tuples.forEach {
dictionary[$0.0] = $0.1
}
print(dictionary) //prints [0: "0", 1: "2"]
Вариант 2: не допускайте нажатия клавиш
enum Errors: Error {
case DuplicatedKeyError
}
do {
try tuples.forEach {
guard dictionary.updateValue($0.1, forKey:$0.0) == nil else { throw Errors.DuplicatedKeyError }
}
print(dictionary)
} catch {
print("Error") // prints Error
}
Ответ 3
Общий подход:
/**
* Converts tuples to dict
*/
func dict<K,V>(_ tuples:[(K,V)])->[K:V]{
var dict:[K:V] = [K:V]()
tuples.forEach {dict[$0.0] = $0.1}
return dict
}
Обновление функционального программирования:
func dict<K,V>(tuples:[(K,V)])->[K:V]{
return tuples.reduce([:]) {
var dict:[K:V] = $0
dict[$1.0] = $1.1
return dict
}
}
Ответ 4
Swift 4
Для создания вы можете использовать родные функции словаря инициализации:
Dictionary(uniqueKeysWithValues: [("a", 0), ("b", 1)])
// ["b": 1, "a": 0]
Dictionary(uniqueKeysWithValues: [("a", 0), ("b", 1), ("b", 2)])
// Fatal error: Duplicate values for key: 'b'
// takes the first match
Dictionary([("a", 0), ("b", 1), ("a", 2)], uniquingKeysWith: { old, _ in old })
// ["b": 1, "a": 0]
// takes the latest match
Dictionary([("a", 0), ("b", 1), ("a", 2)], uniquingKeysWith: { $1 })
// ["b": 1, "a": 2]
Также, если вы хотите иметь ярлык:
Dictionary([("a", 0), ("b", 1), ("a", 2)]) { $1 }
Ответ 5
Улучшен ответ @GitSync с использованием расширения.
extension Array {
func toDictionary<K,V>() -> [K:V] where Iterator.Element == (K,V) {
return self.reduce([:]) {
var dict:[K:V] = $0
dict[$1.0] = $1.1
return dict
}
}
}