Ear*_*rey 31 declarative swift
我想从这个字符串数组中获取
let entries = ["x=5", "y=7", "z=10"]
Run Code Online (Sandbox Code Playgroud)
对此
let keyValuePairs = ["x" : "5", "y" : "7", "z" : "10"]
Run Code Online (Sandbox Code Playgroud)
我试图使用,map但问题似乎是字典中的键值对不是一个独特的类型,它只是在我的脑海中,但不是在字典类型,所以我无法真正提供转换函数,因为有什么都没有改变.再加上map一个阵列,所以不行.
有任何想法吗?
Dav*_*rry 52
斯威夫特4
正如fl034所提到的,这可以通过Swift 4进行简化,其中错误检查版本如下所示:
let foo = entries
.map { $0.components(separatedBy: "=") }
.reduce(into: [String:Int64]()) { dict, pair in
if pair.count == 2, let value = Int64(pair[1]) {
dict[pair[0]] = value
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不希望值为Ints,则更简单:
let foo = entries
.map { $0.components(separatedBy: "=") }
.reduce(into: [String:String]()) { dict, pair in
if pair.count == 2 {
dict[pair[0]] = pair[1]
}
}
Run Code Online (Sandbox Code Playgroud)
较旧的TL; DR
减去错误检查,它看起来非常像:
let foo = entries.map({ $0.componentsSeparatedByString("=") })
.reduce([String:Int]()) { acc, comps in
var ret = acc
ret[comps[0]] = Int(comps[1])
return ret
}
Run Code Online (Sandbox Code Playgroud)
使用map将其[String]转换为拆分[[String]],然后[String:Int]使用reduce 构建字典.
或者,通过添加扩展名Dictionary:
extension Dictionary {
init(elements:[(Key, Value)]) {
self.init()
for (key, value) in elements {
updateValue(value, forKey: key)
}
}
}
Run Code Online (Sandbox Code Playgroud)
(相当有用的扩展顺便说一下,你可以用它来进行字典上的很多map/filter操作,真的很遗憾它默认不存在)
它变得更简单:
let dict = Dictionary(elements: entries
.map({ $0.componentsSeparatedByString("=") })
.map({ ($0[0], Int($0[1])!)})
)
Run Code Online (Sandbox Code Playgroud)
当然,您也可以组合两个地图调用,但我更喜欢拆分各个变换.
如果要添加一些错误检查,flatMap可以使用而不是map:
let dict2 = [String:Int](elements: entries
.map({ $0.componentsSeparatedByString("=") })
.flatMap({
if $0.count == 2, let value = Int($0[1]) {
return ($0[0], value)
} else {
return nil
}})
)
Run Code Online (Sandbox Code Playgroud)
同样,如果你愿意,你可以明显地合并map到flatMap或将它们分割为简单起见.
let dict2 = [String:Int](elements: entries.flatMap {
let parts = $0.componentsSeparatedByString("=")
if parts.count == 2, let value = Int(parts[1]) {
return (parts[0], value)
} else {
return nil
}}
)
Run Code Online (Sandbox Code Playgroud)
一种方法是使用map和reduce以元组作为中间值的两个阶段,例如:
let entries = ["x=5", "y=7", "z=10"]
let dict = entries.map { (str) -> (String, String) in
let elements = str.characters.split("=").map(String.init)
return (elements[0], elements[1])
}.reduce([String:String]()) { (var dict, kvpair) in
dict[kvpair.0] = kvpair.1
return dict
}
for key in dict.keys {
print("Value for key '\(key)' is \(dict[key]).")
}
Run Code Online (Sandbox Code Playgroud)
输出:
Value for key 'y' is Optional("7").
Value for key 'x' is Optional("5").
Value for key 'z' is Optional("10").
Run Code Online (Sandbox Code Playgroud)
或者使用reduce具有相同输出的单个:
let entries = ["x=5", "y=7", "z=10"]
let dict = entries.reduce([String:String]()) { (var dict, entry) in
let elements = entry.characters.split("=").map(String.init)
dict[elements[0]] = elements[1]
return dict
}
for key in dict.keys {
print("Value for key '\(key)' is \(dict[key]).")
}
Run Code Online (Sandbox Code Playgroud)
使用Swift 4的新reduce(into: Result)方法:
let keyValuePairs = entries.reduce(into: [String:String]()) { (dict, entry) in
let key = String(entry.first!)
let value = String(entry.last!)
dict[entry.first!] = entry.last!
}
Run Code Online (Sandbox Code Playgroud)
当然,可以改进String的拆分.