我正在尝试在数组上使用reduce
函数:
var fields = ["gender", "name", "nickname"]
var stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
res[field] = json[field] ?? ""
return res
}
它只是通过fields
数组并将json对象的值赋给res
。
对我来说似乎很简单,但编译器一直在说:
错误:无法通过下标分配:'res'是'let'常量
就行:
res[field] = json[field] ?? ""
这对我没有任何意义,因为我从未将res
或stats
指定为let
。
答案 0 :(得分:9)
闭包参数(除非用inout
声明)是隐式常量,就像用let
声明一样。
如果你想修改它,那么你必须先制作可变副本:
let stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
var res = res
res[field] = json[field] ?? ""
return res
}
从 Swift 4 开始,您可以使用reduce(into:_:)
:
let stats = fields.reduce(into: [String:String]()) { (res, field) in
res[field] = json[field] ?? ""
}
此处res
是" inout"参数可以在闭包中变异。
这样效率更高,因为每个都没有制作副本
迭代步骤。
一个不同的Swift 4解决方案是创建一个新词典 通过将每个字段映射到键/值对:
let stats = Dictionary(uniqueKeysWithValues: fields.map { ($0, json[$0] ?? "") })
答案 1 :(得分:2)
在Swift参数中是不可变的,你不能改变作为参数接收的字典
res[field] = json[field] ?? ""
let json: [String:Any] = ...
let fields = ["gender", "name", "nickname"]
let stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
var res = res
res[field] = (json[field] as? String) ?? ""
return res
}