tech_human
tech_human

Reputation: 7100

Swift - Adding value to an array inside a dictionary

I have an array of objects which I want to store it in dictionary based on student id. In my dictionary my key is of type String and value is an array of string. How do I append the values in the array?

My student array:

var studentArray = [Student(id: '1', subject: 'History'), Student(id: '2', subject: 'History'), Student(id:'1', subject: 'Maths')]

My final dictionary should be like:

{'1': ['History', 'Maths'], '2': ['History']}

My code:

var dictionary = [String, [String]]()
for student in studentArray {
   dictionary.updateValue(student.subject, forKey: student.id)
}

This gives me output as:

{'1': ['Maths'], '2': ['History']}

I tried: dictionary[student.id].append([student.subject]) but this gives me nil output.

How do I append the value to an array inside the dictionary?

Upvotes: 2

Views: 4056

Answers (3)

Vin Gazoil
Vin Gazoil

Reputation: 2020

Not tested but this should works:

var dictionary = [String: [String]]()

for student in studentArray {
    if dictionary[student.id] == nil {
        dictionary[student.id] = [String]()
    }
    dictionary[student.id]?.append(student.subject)
}

Upvotes: 0

Alexander
Alexander

Reputation: 63167

Everyone here is overcomplicating this. There's a dedicated API for this task lol

struct Student {
    let id: Int
    let subject: String
}

let students = [
    Student(id: 1, subject: "History"),
    Student(id: 2, subject: "History"),
    Student(id: 1, subject: "Maths")
]

let subjectsByStudentID = Dictionary
    .init(grouping: students, by: { $0.id })
    .mapValues { students in students.map { $0.subject } }

print(subjectsByStudentID) // => [2: ["History"], 1: ["History", "Maths"]]

Upvotes: 4

mfaani
mfaani

Reputation: 36287

EDIT: Thanks to Martin's comment. The snippet below is the the most succinct answer I can think of. I was initially coming at it from a wrong direction. and I was getting an error. See comments

struct Student { 
    let id: Int
    let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {

    (dict[student.id, default: []]).append(student.subject)
}

print(dict)

Previous answers:

struct Student { 
    let id: Int
    let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {
    var subjects = dict[student.id] ?? [String]()
    subjects.append(student.subject)
    dict[student.id] = subjects
}

print(dict)

Or you can do it this way:

struct Student { 
    let id: Int
    let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {
    if let _ = dict[student.id]{
        dict[student.id]!.append(student.subject)
    }else{
        dict[student.id] = [student.subject]
    }
}

print(dict)

whichever you like

Upvotes: 3

Related Questions