简体   繁体   中英

Nested Swift Dictionaries

I want to initialize a dictionary with a dictionary nested inside like this:

var a = [Int:[Int:Float]]()
a[1][2] = 12

But I get an error:

(Int:[Int:Float]) does not have a member named 'subscript'

I've hacked at a variety of other approaches, all of them running into some kind of issue.

Any idea why this doesn't work?

It's giving you that error because your first subscript returns an optional so it may return a dictionary or nil. In the case that it returns nil the second subscript would be invalid. You can force it to unwrap the optional value by using an exlamation point.

var a = [1 : [ 2: 3.14]]
a[1]
a[1]![2]

If you aren't positive that a[1] is non-nil you may want to safely unwrap with a question mark instead.

var a = [1 : [ 2: 3.14]]
a[1]
a[1]?[2]

You can also assign using this method. (As of Beta 5)

var a = [Int:[Int:Float]]()
a[1] = [Int: Float]()
a[1]?[2] = 12.0
a[1]?[2] //12.0

You can create your own 2D dictionary like this:

struct Dict2D<X:Hashable,Y:Hashable,V> {
    var values = [X:[Y:V]]()
    subscript (x:X, y:Y)->V? {
        get { return values[x]?[y] }
        set {
            if values[x] == nil {
                values[x] = [Y:V]()
            }
            values[x]![y] = newValue
        }
    }
}
var a = Dict2D<Int,Int,Float>()
a[1,2] = 12
println(a[1,2]) // Optional(12.0)
println(a[0,2]) // nil

The point is you access the element via a[x,y] instead of a[x][y] or a[x]?[y] .

Another way to do it is with an extension to the standard dictionary:

extension Dictionary {
    mutating func updateValueForKey(key: Key, updater: ((previousValue: Value?) -> Value)) {
        let previousValue = self[key]
        self[key] = updater(previousValue: previousValue)
    }
}

Example:

var a = [Int:[Int:Float]]()
a.updateValueForKey(1) { nestedDict in
    var nestedDict = nestedDict ?? [Int:Float]()
    nestedDict[2] = 12
    return nestedDict
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM