GuiSoySauce
GuiSoySauce

Reputation: 1783

How to add a extra values for the keys on dictionaries?

For the following variable

var dict2 = ["key1" : "value1", "key2" : [ "value1" , "value2" ]]

How to add a third value for the second key of the following dictionary?

Upvotes: 1

Views: 81

Answers (2)

Antonio
Antonio

Reputation: 72760

@AirspeedVelocity provides a working solution, but requiring a small change to the way the data is defined - but that is what I would do myself, if possible.

However if you have to stick with the original data format, you can use this code:

var dict2: [String : AnyObject] = ["key1" : "value1", "key2" : [ "value1" , "value2" ]]

var array = dict2["key2"] as? [String]
array?.append("value3")
dict2["key2"] = array

First we make explicit the dict2 type, a dictionary using strings as keys and AnyObject as values.

Next we extract the value for the key2 key, and attempt to cast to an array of strings - note that this returns an optional, so the type of array is [String]?

In the next line we add a new element to the array - note that if array is nil, the optional chaining expression evaluates to nil, and nothing happens

In the last line, we set the new array value back to the corresponding key - this step is required because the array is a value type, so when we extract it from the dictionary, we actually get a copy of it - so any update made on it won't be applied to the original array.

Upvotes: 2

Airspeed Velocity
Airspeed Velocity

Reputation: 40963

If I can reformulate your dict2 declaration slightly:

var dict2 = ["key1" : ["value1"], "key2" : [ "value1" , "value2" ]]

then you can append an extra item to key2 like this:

dict2["key2"]?.append("value3")

However, you will probably need to be careful to check that key2 was already present. Otherwise, the above statement will do nothing. In which case you can write:

if dict2["key2"]?.append("value3") == nil {
    dict2["key2"] = ["value3"]
}

Why did I change the original declaration? With the version I gave, dict2 will be of type [String:[String]]. But with your version, what Swift is doing is declaring a much more loosely typed [String:NSObject]. This compiles, but behaves very differently (contents will have reference not value semantics, you will have to do type checks and casts frequently etc), and is probably best avoided.

Upvotes: 4

Related Questions