Reputation: 81
Required extension for Dictionary as to get text key value if exist.
Implemented below code and it is successfully compiled:
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
func getValueForKeyPath(keyValue: String) -> String {
return ((self["item_qty"] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
}
}
But when I did small change in method getting error as:
"Ambiguous reference to member 'subscript' "
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
func getValueForKeyPath(keyValue: String) -> String {
return ((self[keyValue] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
}
}
Please correct me if I am doing anything wrong here.
Upvotes: 2
Views: 1227
Reputation: 11
While the answer by @Hoa compiles, it'll crash under certain circumstances (i.e. when Dictionary.Key
is not a String
).
A better solution might be to use one of the init(...)
methods from the ExpressibleByStringLiteral
protocol.
Notice the extra generic constraint: Key.StringLiteralType == String
. This allows us to use keyValue
to instantiate a Key
object and then use that in self[key]
.
I think we can assume pretty much all strings used are String
, so this shouldn't affect anything.
extension Dictionary where Key: ExpressibleByStringLiteral,
Key.StringLiteralType == String,
Value: AnyObject {
func getValueForKeyPath(keyValue: String) -> String {
let key = Key(stringLiteral: keyValue) // <-- this is key
return ((self[key] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
}
}
As a side note, it might be worth making that return statement a little clearer and easier to debug:
extension Dictionary where Key: ExpressibleByStringLiteral,
Key.StringLiteralType == String,
Value: AnyObject {
func getValueForKeyPath(keyValue: String) -> String {
let key = Key(stringLiteral: keyValue)
guard let dict = self[key] as? Dictionary<String, String>,
let text = dict["text"]
else {
return ""
}
return text
}
}
Upvotes: 1
Reputation: 15804
try to cast keyValue
to Key. For example:
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
func getValueForKeyPath(keyValue : String) -> String{
return ((self[keyValue as! Key] as? Dictionary<String,String>) ?? ["":""])?["text"] ?? ""
}
}
Upvotes: 5