How to unwrap an optional dictionary value in Swift 4+ in one step?

2.2k views Asked by At

Given the dictionary of dictionary below, what is the correct syntax to unwrap the Int? in one step?

let dict:Dictionary<String, Dictionary<String, Int?>> = [
"parentKey" : [
    "firstKey" : 1,
    "secondKey" : nil]
]

let x = "someKey"
let y = "someOtherKey"
var foo = 0

if let goo = dict[x]?[y] { foo = goo } //<-- Error: cannot assign (Int?) to Int

if let goo = dict[x]?[y], let boo = goo { foo = boo } //<-- OK

In the first 'if let', goo is returned as an Int? - goo then needs to be unwrapped as in the second 'if let'...

What is the correct syntax for doing this in one step?

3

There are 3 answers

0
Andrea On BEST ANSWER

As far as I understood you want to force unwrap a double optional. There different methods.

let dbOpt = dict[x]?[y]

My favorite:

if let goo = dbOpt ?? nil { foo = goo } 

Using flatMap:

if let goo = dbOpt.flatMap{$0} { foo = goo } 

Using pattern matching:

if case let goo?? = dbOpt { foo = goo }
0
SirCJ On

Use nil colesecing and provide a default value. Only way to safely unwrap a dictionary value.

if let goo = dict[x]?[y] ?? NSNotFound { foo = goo }  
0
nikksindia On

There are many ways to do this but one of the simplest solution available is :

var foo = 0

if let goo = dict[x]?[y]  as? Int{
    foo = goo
}
print(foo)