Dictionaries [String: [String]] in Swift
Solution 1
First of all...
... you don't really want this
I want to be able to add multiple arrays for a single key.
Instead I think you want...
... to add a string to the array associated to a given string
Example
In other words you want to go from this
["hello":["item 1"]]
to this
["hello":["item 1", "item 2"]]]
So, how to do it?
Let's begin with your dictionary
var dict = [String: [String]]()
dict["hello"] = ["item 1"]
Now you need to extract the array associated to the hello
key
var list = dict["hello"] ?? []
adding a string to it
list.append("item 2")
and finally adding the updated array back into the dictionary
dict["hello"] = list
That's it
Solution 2
This is what your code does
dict["hello"] = ["item 1"]
- This sets hello
to ["item 1"]
dict["hello"] = ["item 2"]
- This sets hello
to ["item 2"]
This is just like a variable, for example:
var hello = Array<String>()
hello = ["item 1"] // prints out ["item 1"]
hello = ["item 2"] // prints out ["item 2"]
This is what is happening with your dictionary. You are overriding any stored data with new data.
The problem with appending. This only works if there is already an array at that key.
dict["hello"]?.append("test")
This wouldn't work.
But this would.
dict["hello"] = ["test 1"]
dict["hello"]?.append("test")
print(dict) // prints out ["dict":["test 1","test"]]
What you need to do
var dict = Dictionary<String,Array<String>>()
func add(string:String,key:String) {
if var value = dict[key] {
// if an array exist, append to it
value.append(string)
dict[key] = value
} else {
// create a new array since there is nothing here
dict[key] = [string]
}
}
add(string: "test1", key: "hello")
add(string: "test2", key: "hello")
add(string: "test3", key: "hello")
print(dict) // ["hello": ["test1", "test2", "test3"]]
Dictionary Extension
extension Dictionary where Key == String, Value == Array<String> {
mutating func append(_ string:String, key:String) {
if var value = self[key] {
// if an array exist, append to it
value.append(string)
self[key] = value
} else {
// create a new array since there is nothing here
self[key] = [string]
}
}
}
How to use
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var dict = Dictionary<String,Array<String>>()
dict.append("first", key: "hello")
dict.append("second", key: "hello")
dict.append("thrid", key: "hello")
dict.append("one", key: "goodbye")
dict.append("two", key: "goodbye")
print(dict) // ["hello": ["first", "second", "thrid"], "goodbye": ["one", "two"]]
}
Solution 3
Other people have the correct solution. Here is a quick shorthand for the same answer.
var dict = [String: [String]]()
dict["hello"] = (dict["hello"] ?? []) + ["item 1"]
dict["hello"] = (dict["hello"] ?? []) + ["item 2"]
In Swift 4, this will be
var dict = [String: [String]]()
dict["hello"] = dict["hello", default: []] + ["item 1"]
dict["hello"] = dict["hello", default: []] + ["item 2"]
Solution 4
Please try this thing and let me know if this is what you require
import UIKit
var dict = [String: [String]]()
if var value = dict["hello"]{
value.append("Hi")
dict["hello"] = value
}else{
dict["hello"] = ["item 1"]
}
Cesare
Updated on July 16, 2022Comments
-
Cesare almost 2 years
I have a dictionary that looks like this:
var dict = [String: [String]]()
I want to be able to add multiple arrays for a single key. This works fine:
dict["hello"] = ["item 1"]
But when I assign a new array the previous value is obviously overwritten - we want to avoid that:
dict["hello"] = ["item 2"] // overwrites item 1 – how to avoid overwriting?
So I tried to use the
append
method, but this returns nil:dict["hello"]?.append("test") // does nothing? output: ()
How can I append strings to the array (value) of a certain key in Swift?
-
Cesare almost 7 yearsWhile this works if there is at least a value for a certain key, I want to be able to set the value for a key regardless if the dictionary contains a value for a specific key or not.
-
Usama Sadiq almost 7 yearsyou can set the new value in else block. check the edited code
-
Cesare almost 7 yearsPretty neat, Tristan! Could this be further developed into an extension?
-
Hamish almost 7 yearsIn Swift 4, just
dict["hello", default: []].append("item 1")
:) -
Cesare almost 7 years
No + candidates produce the expected contextual result type [String]
-
Tristan Beaton almost 7 yearsI have added the extension. @Cesare
-
Jeffery Thomas almost 7 years@Cesare hmm… don't know what to say. This test in Xcode 8.3.1 playground and Xcode 9 Beta playground. It uses the
+
operator for Arrays.