Search code examples
swiftperformancedictionary

Swift: Making dictionary array values mutable


This is a coding pattern I use frequently in other languages, e.g. Obj-C:

I have a dictionary whose values are arrays, to which I may add zero or more items.

I wrote this code in Swift 5:

var intsForString = [String:[Int]]()

func add(value: Int, forKey: String) {
    var ints = intsForString[forKey]
    if ints == nil {
        ints = [Int]()
        intsForString[forKey] = ints
    }
    ints!.append(value)
}

add(value: 1, forKey: "a")
add(value: 2, forKey: "a")

print("\(intsForString["a"]!)") // prints an empty array instead of `[1,2]`

I had expected that I could get a reference to the ints value in the dictionary and then modify it. However, it appears I get a copy of the array in the dict, and when I modify the ints array, it will not update the array stored in the dict.

Is there a way to get a mutable reference to the array in the dictionary, without resorting to NSDictionary and NSArray?

Work-around

I can, as a work-around, update the array inside the dictionary by moving the line

intsForString[forKey] = ints

past the ints!.append(value) line.

However, I find that inefficient, because that requires another key lookup, and it also leads to the array being needlessly copied and re-created, then disposed again.


Solution

  • Instead of that function you can do

    intsForString["a",default: []].append(1)