sfyfedotcom
sfyfedotcom

Reputation: 69

Error accessing Swift dictionary value

I'm using a provided value to access an array value from a dictionary:

print("thisFrom "+thisFrom)
print(values[thisFrom])
let ingredientArr = values[thisFrom] as! [String: Float]

But this is the output:

thisFrom cup
Optional(["butter": 226.80000000000001, "caster sugar": 225.00730999999999, "granulated sugar": 200.0, "tbsp": 16.0, "ml": 236.58823649999999, "flour": 125.0, "tsp": 48.0, "icing sugar": 125.0])
fatal error: unexpectedly found nil while unwrapping an Optional value

I don't understand how it can be returning nil , when the print lines show the value and resulting array are valid.

I'm using Swift 3.

Upvotes: 0

Views: 113

Answers (3)

FelixSFD
FelixSFD

Reputation: 6092

values[thisFrom] is not of the type [String: Float]. It is [String: Double] instead.

Why?

Let's have a look at the value for the key "butter": It is a floating-point number with a precision of more than 6 decimal digits. So it can't be Float. That's why the force-cast fails.

Upvotes: 1

donnywals
donnywals

Reputation: 7591

When I put this code in a playground:

let values: [String: Any?] = ["cup": ["butter": 226.80000000000001, "caster sugar": 225.00730999999999, "granulated sugar": 200.0, "tbsp": 16.0, "ml": 236.58823649999999, "flour": 125.0, "tsp": 48.0, "icing sugar": 125.0]]

let thisFrom = "cup"
let ingredientArr = values[thisFrom] as! [String: Float]

Xcode gives me the error you're seeing. If I change the line that throws the unwrapping error to

let ingredientArr = values[thisFrom] as! [String: Double]

It works fine.

Seems like your dictionary is of type [String: Double], not [String: Float].

I would recommend that you change the forced cast to an optional one like this:

if let ingredientArr = values[thisFrom] as? [String: Double] {
    // safely casted to [String: Double]
}

Upvotes: 0

andyvn22
andyvn22

Reputation: 14824

The unwrap it's referring to is the exclamation point after as. What you've written is the same as:

let optionalAttemptedCast = values[thisFrom] as? [String: Float]
let ingredientArray = optionalAttemptedCast!

Hopefully this makes it clear that what is failing is the cast. That is, values[thisFrom] does indeed exist, as you saw from your print(), but it is not convertible to type [String: Float].

Upvotes: 0

Related Questions