如何从元组数组创建字典?

Posted

技术标签:

【中文标题】如何从元组数组创建字典?【英文标题】:How do I create dictionary from array of tuples? 【发布时间】:2017-04-28 15:39:27 【问题描述】:

假设我有一组可以识别的对象,我想从中创建字典。我可以像这样轻松地从数组中获取元组:

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
        
    

【问题讨论】:

为什么要默认?没有将元组数组映射到字典的通用方法。在字典中,每个键都必须是唯一的,在元组数组中,允许任意数量的重复 keys。拿他们怎么办?改写?忽略? 是的,@user28434 是对的。顺便说一句,看看这个***.com/a/31447400/4272498 是的,你说得对@user28434,我没想到。 你为什么要创建一个元组数组?您可以直接使用 myArray 中的数据创建字典。 【参考方案1】:

斯威夫特 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"]

【讨论】:

我不知道为什么这被否决了,因为这是解决 OP 提出的问题的最合适的方法。 我❤️这个答案!【参考方案2】:

斯威夫特 4

为了创建,您可以使用本机 Dictionary 的 init 函数:

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  
// ["b": 1, "a": 2]

【讨论】:

【参考方案3】:

根据你想做什么,你可以:

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

【讨论】:

【参考方案4】:

通用方法:

/**
 * 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
    

【讨论】:

@hasen 这值得商榷。由于您将元组作为参数传递,因此绝对不应该只是 func。将其设为静态明确表示它无法更改其所在类的状态 它不需要驻留在类中。这只是一个功能。 Swift 不是 Java。 @hasen 我想这是自以为是的 ? 为了简洁起见,我将其更改为 func。感谢您的意见。 我把这个函数作为字典扩展初始化。 @DanielT。已经有一个原生的了:init(uniqueKeysWithValues:) ? (swift 4)【参考方案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
        
    

【讨论】:

【参考方案6】:

更新到@Stefan 的回答。

extension Array 

    func toDictionary<K, V>() -> [K: V] where Iterator.Element == (K, V) 
        return Dictionary(uniqueKeysWithValues: self)
    

【讨论】:

以上是关于如何从元组数组创建字典?的主要内容,如果未能解决你的问题,请参考以下文章

(Swift)如何从元组数组[(Date, MyClass)]中获取元组元素(Date, MyClass)的索引?

查询 Python 字典以从元组中获取值

如果键匹配,如何从元组中提取一个值

Javascript:使用元组作为字典键

如何使用子元组从元组创建列表?

打字稿从元组/数组值派生联合类型