Dictionaries [String: [String]] in Swift

14,999

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"]
}
Share:
14,999
Cesare
Author by

Cesare

Updated on July 16, 2022

Comments

  • Cesare
    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
    Cesare almost 7 years
    While 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
    Usama Sadiq almost 7 years
    you can set the new value in else block. check the edited code
  • Cesare
    Cesare almost 7 years
    Pretty neat, Tristan! Could this be further developed into an extension?
  • Hamish
    Hamish almost 7 years
    In Swift 4, just dict["hello", default: []].append("item 1") :)
  • Cesare
    Cesare almost 7 years
    No + candidates produce the expected contextual result type [String]
  • Tristan Beaton
    Tristan Beaton almost 7 years
    I have added the extension. @Cesare
  • Jeffery Thomas
    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.