如何从元组数组创建字典?
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)
【讨论】:
以上是关于如何从元组数组创建字典?的主要内容,如果未能解决你的问题,请参考以下文章