我无法弄清楚Swift 2的特殊风格 map
:
我正在读一本字典(来自一个plist文件),所以我有一个 [String: AnyObject]
:
let dictionary = NSDictionary(contentsOfFile: path) as? [String: AnyObject]
我的目标是从字典转换 Strings
到记录器实例的字典中。这将是 [String: XCGLogger]
:
let loggers = dictionary
.map { (n, l) in [ n: newLogger(l.0, withLevel: level(l.1)) ] }
然而,这是回归 [[String: XCGLogger]]
(看起来像是一系列字典给我)。问题是如何返回扁平字典。当我尝试使用时 flatMap
我开始围绕关于闭包的错误或者无法在类型上调用flatMap (Key, Value) -> NSDictionary
。
原因是 map
只能返回数组,而不能返回字典。要获得字典,您有几种策略,例如:
var loggers : [String: XCGLogger] = [:]
dictionary.map{(n, l) in loggers[n] = newLogger(l.0, withLevel: level(l.1))}
也许:
var loggers : [String: XCGLogger] = [:]
for (n, l) in dictionary {
loggers[n] = newLogger(l.0, withLevel: level(l.1))
}
记录仪
原因是 map
只能返回数组,而不能返回字典。要获得字典,您有几种策略,例如:
var loggers : [String: XCGLogger] = [:]
dictionary.map{(n, l) in loggers[n] = newLogger(l.0, withLevel: level(l.1))}
也许:
var loggers : [String: XCGLogger] = [:]
for (n, l) in dictionary {
loggers[n] = newLogger(l.0, withLevel: level(l.1))
}
记录仪
extension SequenceType {
func toDict<K : Hashable, V>
(@noescape convert: Generator.Element -> (K, V)) -> [K:V] {
var result: [K:V] = [:]
for x in self {
let (key, val) = convert(x)
result[key] = val
}
return result
}
}
dictionary.toDict { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) }
要么
extension Dictionary {
public init<
S : SequenceType where
S.Generator.Element == (Key, Value)
>(_ seq: S) {
self.init()
for (k, v) in seq { self[k] = v }
}
}
extension SequenceType {
func toDict<K : Hashable, V>
(@noescape convert: Generator.Element -> (K, V)) -> [K:V] {
return Dictionary(lazy(self).map(convert))
}
}
dictionary.toDict { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) }
要么
extension Dictionary {
func map<K : Hashable, V>(@noescape transform: (Key, Value) -> (K, V)) -> [K:V] {
var result: [K:V] = [:]
for x in self {
let (key, val) = transform(x)
result[key] = val
}
return result
}
}
dictionary
.map { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) }
@ Renzo的答案稍微简洁一点就是使用reduce:
let loggers: [String: XCGLogger] = dictionary.reduce([:]){(var loggers, kv) in
loggers[kv.0] = newLogger(kv.1.0, withLevel: level(kv.1.1))
return loggers
}
如果Swift可以将kv破坏为(key,value),那将更方便,更清晰。希望未来版本的Swift,我们将能够做到这一点。