Add New Key/Value to Dictionary - swift

I have a dictionary of type [String: [String]] and is loaded as blank [ : ].
Is there a way I can append a value to the array associated to a new string key? (i.e. exampleDict["test"].append("test"))
When I print out the dictionary after attempting this, I am returned [ : ], which I believe is because the key does not exist and returns as nil.

Swift has a neat "default" feature for doing things exactly like this.
exampleDict["test", default: []].append("test")
If exampleDict["test"] is nil, the default is returned instead. If you modify the returned default object, that modification goes into the dictionary.
Unfortunately this only works properly for value types, since classes aren't reassigned when they're mutated. Fortunately, Array is a value type, so this will work perfectly here.

You have to use Dictionary.subscript(_:default:).
exampleDict["test", default: []].append("test")

Related

How do put multiple values into a single key in Swift?

Is there a way to put multiple values in one key in Swift's dictionary, such as 'multimap' in Java?
var multiDic = [String:UserData]()
This is the dictionary I declared. it has this structure.
struct UserData{
var name: String
var id: String
var nickname: String
}
And when I put the value in one key in the dictionary, the value is updated without being stacked.
for key in 1...10 {
multiDic.updateValue(UserData(name:"name+\(key)", id:"id+\(key)", nickname:"nick+\(key)"), forKey: "A")
}
print(multiDic.count)
reults
1
How can I accumulate multiple values on a single key? I looked up a library called 'Buckets'
(https://github.com/mauriciosantos/Buckets-Swift#buckets), but there has been no update since swift 3.0.
Swift dictionary doesn't support this. One work around is to declare the dictionary to hold an array of values, like this:
var multiDic = [String:[UserData]]()
You would have to modify your code for adding values to work with the array instead of updating the value in place.
I haven't tried the "Buckets" project you mention, but for what it's worth, it probably still works either as-is or with minor changes.

How to directly add a key-value pair to a dictionary with "Cannot assign to immutable expression of type" error?

I have a dictionary that contains a JSON object. I'm trying to directly manipulate that dictionary to add a key-value pair. However, I am getting the Cannot assign to immutable expression of type Any error.
I know that the value of Any is immutable, it cannot be changed. I managed to obtain a reference to it to store it in a different dictionary and applied a key-value pair there, but I like to change the original dictionary to reduce code repetition.
Currently this is the output of the dictionary:
dict = ["Object":
[ ["number_1": -117.13,
"number_2": 32.91,
"link": http://www.google.com]
]
]
What I'm trying to do is the following:
( (dict["Object"] as! [Dictionary<String, Any>])[0] as! Dictionary<String, Any>)["image"] = UIImage(named: "")
I'm trying to add "image" as another key with a UIImage as the value, but I can't due to Any being an immutable type.
How can I directly manipulate dict to add a key-value pair?
FYI: dict is declared as a var, not let

How to initialize an array inside a dictionary?

I have a dictionary declared like this:
var myDict = [Int : [Int]]()
The array in it is not initialized, so every time I have to check it first:
if (myDict[idx] == nil) {
myDict[idx] = []
}
How to initialize it as an empty array in MyDict declaration?
I think you could be misunderstanding something pretty key - let's make sure:
The way the dictionary works, is not to have one array, but an array for each key.
Each value of 'idx' you request the array for returns a different array.
You can't expect it to return an empty array - a dictionary is meant to return a nil value for a key that hasn't been set. To do what you're trying, the following would probably do the trick:
myDict[idx] = myDict[idx] ?? []
That's what dictionary do if you try to retrieve a key for which no value exists.
You can subclass Dictionary and override the subscript func to get what you want like this. Or simply write an extension, or write a operator defination to use a different symbol.
“You can also use subscript syntax to retrieve a value from the dictionary for a particular key. Because it is possible to request a key for which no value exists, a dictionary’s subscript returns an optional value of the dictionary’s value type. ”
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2.1).” iBooks. https://itunes.apple.com/cn/book/swift-programming-language/id881256329?l=en&mt=11
You can initialize it this way
myDict.forEach {
(var dictElement) -> () in
dictElement.1 = [Int]()
}

NSUserDefault critical coding in ios9 swift?

I am following a tutorial in which I am saving data in a NSUserDefault type having the following code. It has comments but I can't get what's happening over here-
var todoDictionary = NSUserDefaults.standardUserDefaults().dictionaryForKey(ITEMS_KEY) ?? Dictionary() // if todoItems hasn't been set in user defaults, initialize todoDictionary to an empty dictionary using nil-coalescing operator (??)
todoDictionary[item.UUID] = ["deadline": item.deadline, "title": item.title, "UUID": item.UUID] // store NSData representation of todo item in dictionary with UUID as key
NSUserDefaults.standardUserDefaults().setObject(todoDictionary, forKey: ITEMS_KEY)
NSUserDefaults.standardUserDefaults().setObject(todoDictionary, forKey: ITEMS_KEY)
So what's actually happening here can anyone please explain a bit.
What is the ITEMS_KEY doing here ?
Line 1 is retrieving a dictionary from the UserDefaults with key ITEMS_KEY, when that fails, it instantiates an empty Dictionary(). That is what the null-coalescing operator means. ITEMS_KEY is a property you might have set somewhere (a constant).
Line 2 is setting a key-value to the dictionary.
Line 3 is writing the dictionary back to the NSUserDefaults.
Line 4 is double? Not sure if that is right.

Swift Spritekit setvalue

In swift with spritekit I want to set a variable of a sprite so I tried to say
p.setValue(value: (String(c)), forKey: "co")
But this gives an error.
So the main question is:
How can i set a key value pair in a sprite to a string
as a key and an int/string as a value?
setValue(_:forKey:) and related methods aren't for associating arbitrary key/value data with an object. They're part of Key-Value Coding, a Cocoa feature that does all sorts of handy things — but unless a class does something special with KVC, all setValue(_:forKey:) does is let you set one of that class's declared properties using a string instead of by directly accessing a property. In other words, the two lines below are equivalent:
node.name = "foo"
node.setValue("foo", forKey: "name")
If you want to associate arbitrary key-value pairs with your sprites—which can be a great way to keep track of entities in your game—use the userData property.
To use setValue:forKey: you need to have (a) a valid key, and (b) a value of the correct type for that key. For example:
mySprite.setValue(UIColor.redColor(), forKey: "co") // error, "co" isn't a valid key
mySprite.setValue("red", forKey: "color") // error, "color" needs a UIColor value
mySprite.setValue(UIColor.redColor(), forKey: "color") // works!
What value and key are you actually using?