senty
senty

Reputation: 12857

Adding 'Key:Value' in Multidimensional Dictionary is Overwriting

I declared and initialized a [[String:[String:String] dictionary. It's empty in the beginning, and I am trying to add multiple values under the parent keys.

var dictionary = [String:[String:String]

// some checks

dictionary[i] = ["name" : name]
dictionary[i] = ["from" : country]
dictionary[i] = ["age" : age]

When I do that, I end up having only age key as a child under [key: [String:String]. So it's overwriting when I use this approach.

What is the appropriate way of doing

Upvotes: 0

Views: 89

Answers (3)

vacawama
vacawama

Reputation: 154671

You can use optional chaining to assign to the inner dictionary, but you need to create the inner dictionary first.

// create the dictionary of dictionaries
var dictionary = [String:[String:String]]()

// some example constants to make your code work    
let i = "abc"
let name = "Fred"
let country = "USA"
let age = "28"

// Use nil coalescing operator ?? to create    
// dictionary[i] if it doesn't already exist
dictionary[i] = dictionary[i] ?? [:]

// Use optional chaining to assign to inner dictionary
dictionary[i]?["name"] = name
dictionary[i]?["from"] = country
dictionary[i]?["age"] = age

print(dictionary)

Output:

["abc": ["age": "28", "from": "USA", "name": "Fred"]]

Using these techniques, here's my version of @matt's insert(_:value:at:) function:

func insert(key:String, value:String, at k:String) {
    dictionary[k] = dictionary[k] ?? [:]
    dictionary[k]?[key] = value
}

Upvotes: 0

matt
matt

Reputation: 535746

func insert(key:String, value:String, at k:String) {
    var d = dictionary[k] ?? [String:String]()
    d[key] = value
    dictionary[k] = d
}

And here's how to test it:

insert("name", value: name, at: i)
insert("from", value: country, at: i)
insert("age", value: age, at: i)

Upvotes: 0

Paulw11
Paulw11

Reputation: 114975

Your code is creating a new dictionary on each line and assigning this in the dictionary for key i, so you end up with the last dictionary ["age" : age]

You need to create an inner dictionary, assign the values to this and then assign this to your outer dictionary;

var innerDict = [String:String]()
innerDict["name"] = name
innerDict["from"] = from
innerDict["age"] = age

dictionary[i] = innerDict

I would suggest, however, that you look at creating a Struct and put that in your outer dictionary rather than using a dictionary of dictionaries

Upvotes: 2

Related Questions