Swift error when trying to access Dictionary: `Could not find member 'subscript'`

后端 未结 4 883
半阙折子戏
半阙折子戏 2021-02-04 08:08

This won\'t compile: \"enter I\'ve tried a couple different things; different ways of declaring th

相关标签:
4条回答
  • 2021-02-04 08:25

    response is declared as such:

    var response = Dictionary<String,Any>()
    

    So the compiler thinks response["current_rates"] will return an Any. Which may or may not be something that is subscript indexable.

    You should be able to define you type with nested Dictionaries, 3 levels and eventually you get to a float. You also need to drill in with optional chaining since the dictionary may or may not have a value for that key, so it's subscript accessor returns an optional.

    var response = Dictionary<String,Dictionary<String,Dictionary<String,Float>>>()
    // ... populate dictionaries
    println(response["current_rates"]?["a"]?["b"]) // The float
    
    0 讨论(0)
  • 2021-02-04 08:27

    Let's take a look at

    response["current_rates"][exchange][currency]
    

    response is declared as Dictionary<String,Any>(), so after the first subscript you try to call another two subscripts on an object of type Any.

    Solution 1. Change the type of response to be a nested dictionary. Note that I added the question marks because anytime you access a dictionary item you get back an optional.

    var response = Dictionary<String,Dictionary<String,Dictionary<String, Float>>>()
    
    func valueForCurrency(currency :String, exchange :String) -> Float? {
        return response["current_rates"]?[exchange]?[currency]
    }
    

    Solution 2. Cast each level to a Dictionary as you parse. Make sure to still check if optional values exist.

    var response = Dictionary<String,Any>()
    
    func valueForCurrency(currency :String, exchange :String) -> Float? {
        let exchanges = response["current_rates"] as? Dictionary<String,Any>
    
        let currencies = exchanges?[exchange] as? Dictionary<String,Any>
    
        return currencies?[currency] as? Float
    }
    
    0 讨论(0)
  • 2021-02-04 08:29

    You can get nested dictionary data by following these steps:

    let imageData: NSDictionary = userInfo["picture"]?["data"]? as NSDictionary
    let profilePic = imageData["url"] as? String
    
    0 讨论(0)
  • 2021-02-04 08:50
    func valueForCurrency(currency :String, exchange :String) -> Float? {
        if let exchanges = response["current_rates"] as? Dictionary<String,Any> {
            if let currencies = exchanges[exchange] as? Dictionary<String,Any> {
                return currencies[currency] as? Float
            }
        }
        return nil
    }
    
    0 讨论(0)
提交回复
热议问题