Curt Rand
Curt Rand

Reputation: 1045

Swift: How to keep updating a Dictionary inside another Dictionary correctly?

This is a little hard to explain, but I'll try my best. I am trying to update a Dictionary inside another Dictionary properly. The following code almost does what I need.

var dictionary = Dictionary<String, [Int : Int]>()

func handleStatsValue(tag: Int ) {
        let currentValue: Int = dictionary["Score"]?[tag] ?? 0

        dictionary["Score"] = [
            tag : currentValue + 1
        ]
 }

However, it seems the dictionary is overridden when the tag value changes (e.g. 1 to 2). I need Dictionary to have multiple dictionaries inside of it. Any tips or suggestions are deeply appreciated.

Edit: I'm trying to have multiple dictionaries nested inside a dictionary. It seems whenever the tag value is changed, the dictionary is overridden.

Upvotes: 0

Views: 79

Answers (2)

Sulthan
Sulthan

Reputation: 130132

One way to write this would be:

func handleStatsValue(tag: Int) {
    dictionary["Score", default: [:]][tag, default: 0] += 1
}

or, written without [_:default:]

func handleStatsValue(tag: Int) {
    var scoreDictionary = dictionary["Score"] ?? [:]
    scoreDictionary[tag] = (scoreDictionary[tag] ?? 0) + 1
    dictionary["Score"] = scoreDictionary
}

However, it's not a good idea to use nested dictionaries to keep your data. Use a custom struct instead and try to avoid tags too:

struct DataModel {
    var score: [Int: Int] = [:]
}

Upvotes: 2

Joakim Danielson
Joakim Danielson

Reputation: 52013

I think you need something like this to either increase the value for an existing tag or add a new tag if it doesn't exist

func handleStatsValue(tag: Int ) {
    if var innerDict = dictionary["Score"] {
        if let value = innerDict[tag] {
            innerDict[tag] = value + 1
        } else {
            innerDict[tag] = 1
        }
        dictionary["Score"] = innerDict
    }    
}

Although the code looks a bit strange with the hardcoded key "Score", maybe it would be better to have multiple simple dictionaries instead, like

var score: [Int, Int]()

or if you prefer

var score = Dictionary<Int, Int>()

Upvotes: 0

Related Questions