Tropicano
Tropicano

Reputation: 361

Swift - Array to Dictionary

So, I have the following objects:

struct Person {
   let name: String
   let birthday: String
}

let Bob = Person(name: "Bob", birthday: "11.12.1987")
let Tim = Person(name: "Tim", birthday: "11.12.1987")
let John = Person(name: "John", birthday: "01.02.1957")
let Jerry = Person(name: "Jerry", birthday: "17.12.2001")

And the following array:

let people = [Bob, Tim, John, Jerry]

My goal is to generate a dictionary from this array, with "birthday" for the key and the "Person" object itself as the value: [String: [Person]]. If there are equal keys the person should be added and form an array as a key. So the result will be the following:

dictionary = ["11.12.1987": [Bob, Tim], "01.02.1957": John, "17.12.2001": Jerry]

What is the best way to achieve this?

Cheers!

Upvotes: 1

Views: 86

Answers (2)

Sandeep
Sandeep

Reputation: 21164

You could use Dictionary(grouping:by:) method together with mapValues,

let result = Dictionary(grouping: people, by: \.birthday)

print(result)

Output is,

["01.02.1957": ["John"], "17.12.2001": ["Jerry"], "11.12.1987": ["Bob", "Tim"]]

This would yield you a Dictionary of type Dictionary<String, [Person]>.

From, your question it seems like you want a Person if there is only one Person and array when there are multiple people. You would loose type in that situation and your type would be something like this, Dictionary<String, Any>. You could make small bit of modification to the above code to do that.

let result = Dictionary(grouping: people, by: \.birthday)
    .mapValues { people -> Any in
                if people.count == 1 {
                    return people.first!
                }
                return people
            }

print(result)

The output would be similar to what you want,

["01.02.1957": "John", "17.12.2001": "Jerry", "11.12.1987": ["Bob", "Tim"]]

Upvotes: 3

Cristian
Cristian

Reputation: 72

What about a loop through the dictionary checking if date exists. Otherwise create key with date and assign value. If key already exists append person to the actual key value:

var dictionary = [String: [Person]]()
        
        // Loop through all person objects in array
        for person in people {
            
            // Check if date already exists
            if dictionary[person.birthday] != nil {
                // If already exists, include new person in array
                var array = dictionary[person.birthday]
                array!.append(person)
            }
            // If date does not exists, add new key with date and person
            else {
                dictionary[person.birthday] = [person]
            }
            
        }

Upvotes: 0

Related Questions