我正在寻找最好的方法如何将此代码改为一行:
if (dictionary["Amoumt"] is Double) {
amount = dictionary["Amount"] as Double
} else {
amount = NSString(string: dictionary["Amount"] as String).doubleValue
}
我有Dictionary<String, AnyObject>
,我想解析它的值。我正在使用上面的代码但它的行太多了。我想把它变成一条线。类似的东西:
dictionary["Amount"].parseDouble()
使用此方法创建扩展程序没有问题:
func parseDouble() -> Double {
if (self is Double) {
return self as Double
} else {
return NSString(string:(self as String)).doubleValue
}
}
但是我应该扩展哪种类型?接下来你能用通用方法帮我吗?所以我可以这样说:
dictionary["Amount"].parse(Double)
这是如何做到这一点的好方法,还是我应该采取另一种方式?
答案 0 :(得分:1)
也许你正在寻找这种扩展:
extension Dictionary{
func parseDouble(key:Key) -> Double {
let result = self[key]
if (result is Double) {
return result as Double
} else {
return NSString(string:(result as String)).doubleValue
}
}
}
使用以下方法获取密钥的价值:
var doubleValue = dictionary.parseDouble("amount")
一个通用函数
extension Dictionary{
func parse<T>(key:Key) -> T? {
let result = self[key]
if (result is T) {
return result as? T
}
return nil
}
}
var doubleValue:Double? = myDistionary.parse("someKeyForDouble")
var stringValue:String? = myDistionary.parse("someKeyForString")
答案 1 :(得分:1)
您可以按原样使用AnyObject
。尝试:
var dictionary:[String:AnyObject] = [
"foo": 4.21, // NSNumber
"bar": "42.5", // NSString
"baz": [1,2,3], // NSArray
]
let foo = dictionary["foo"]?.doubleValue ?? 0 // -> 4.21
let bar = dictionary["bar"]?.doubleValue ?? 0 // -> 42.5
let baz = dictionary["baz"]?.doubleValue ?? 0 // -> 0.0
这是有效的,因为NSNumber
和NSString
都有.doubleValue
属性。
另一方面,NSArray
没有该属性,在这种情况下,它返回nil
。
如the document中所述:
您还可以调用任何Objective-C方法并访问任何属性,而无需转换为更具体的类类型。这包括标有
@objc
属性的Objective-C兼容方法。
答案 2 :(得分:0)
最简单的方法是使用nil合并运算符和可选的double。这会尝试将值转换为double。如果成功,则将其解包,如果失败,则默认为第二个值,即转换为“dict [amount]&#39;到一个字符串并取其双倍值。
var amount: Double? = nil
let dict: [String: AnyObject] = ["amount" : "1.2"]
amount = (dict["amount"] as? Double) ?? NSString(string: dict["amount"] as! String).doubleValue
为了实现你的功能:
func getDouble(obj: AnyObject) -> Double {
return (obj as? Double) ?? NSString(string: obj as! String).doubleValue
}
然后使用getDouble(dict["amount"])
调用它。对我这样的事情的延伸可能在我看来有点过分了。
答案 3 :(得分:0)
如果你想要一个扩展名,那么理论上最好的地方就是AnyObject
- 因为它是你要转换的AnyObject
。
但是AnyObject
实际上是一个协议,所以你无法扩展它。
我不建议将它作为Dictionary
的扩展名 - 将类型强制转换为双精灵并不是与字典有任何关系。
所以最好的方法是将它作为自由函数而不是作为扩展:
func getDouble(obj: AnyObject?) -> Double {
return (obj as? Double) ?? (obj as? NSString)?.doubleValue ?? 0
}
asDouble(dictionary["Amount"])
注意,如果你传递一个既不是double也不是字符串的函数,这个函数是安全的。使用as
或!
而不是as?
的其他解决方案在运行时会因为其他内容传递而崩溃。
你可以说它应该返回一个可选项,如果该值不能转换为double,则返回nil。这就是String.toInt()
的作用。不幸的是,NSString.doubleValue
的限制是它没有这样做 - 它默认为零 - 所以你不能将这两种方法结合起来。