Как создать словарь из массива кортежей?

предположим, у меня есть массив объектов, которые можно идентифицировать, и я хочу создать словарь из него. Я могу легко получить кортежи из моего массива, например:

let tuples = myArray.map { return (.id, ) }

но я не вижу инициализатора для словаря, чтобы взять массив кортежей. Я что-то упускаю? Есть ли у меня расширение для словаря для этой функции (на самом деле это не сложно, но я думал, что он будет предоставлен по умолчанию) или есть более простой способ сделать это?

есть код для расширение

extension Dictionary
{
    public init (_ arrayOfTuples : Array<(Key, Value)>)
    {
        self.init(minimumCapacity: arrayOfTuples.count)

        for tuple in arrayOfTuples
        {
            self[tuple.0] = tuple.1
        }
    }
}

4 ответов


в зависимости от того, что вы хотите сделать, вы могли бы:

let tuples = [(0, "0"), (1, "1"), (1, "2")]
var dictionary = [Int: String]()

Вариант 1: заменить существующие ключи

tuples.forEach {
    dictionary[.0] = .1
}    
print(dictionary) //prints [0: "0", 1: "2"]

Вариант 2: Не разрешать повторное нажатие клавиш

enum Errors: Error {
    case DuplicatedKeyError
}

do {
    try tuples.forEach {
        guard dictionary.updateValue(.1, forKey:.0) == nil else { throw Errors.DuplicatedKeyError }
    }
    print(dictionary)
} catch {
    print("Error") // prints Error
}

Swift 4

Если ваши кортежи (Hashable, String), вы можете использовать:

let array = [("key1", "value1"), ("key2", "value2"), ("key3", "value3")]
let dictionary = array.reduce(into: [:]) { [.0] = .1 }
print(dictionary) // ["key1": "value1", "key2": "value2", "key3": "value3"]

общий подход:

/**
 * Converts tuples to dict
 */
func dict<K,V>(_ tuples:[(K,V)])->[K:V]{
    var dict:[K:V] = [K:V]()
    tuples.forEach {dict[.0] = .1}
    return dict
}

обновление функционального программирования:

func dict<K,V>(tuples:[(K,V)])->[K:V]{
    return tuples.reduce([:]) {
       var dict:[K:V] = 
       dict[.0] = .1   
       return dict
    }
}

улучшенный ответ @GitSync с использованием расширения.

extension Array {
    func toDictionary<K,V>() -> [K:V] where Iterator.Element == (K,V) {
        return self.reduce([:]) {
            var dict:[K:V] = 
            dict[.0] = .1
            return dict
        }
    }
}