Reputation: 589
How do I iterate over an array of objects to derive totals to use in my views. Secondly, where should I run this function so the derived totals are reusable in other parts of the app?
I'm trying to reach for the reduce(_:_:)
array method but I don't know if this the best approach.
I'm needing to sum the total students in each grade. i.e., Grade 10 has 2 Students. Grade 11 has 1 Student. Grade 12 has 3 Students.
I've been stuck on this for a while. Thank You!
import SwiftUI
struct Student: Identifiable {
let id: String
let name: String
let gradeLevel: Int
}
class GetStudents: ObservableObject {
@Published var items = [Student]()
init() {
self.items = [
Student(id: "aa1", name: "Bobby", gradeLevel: 12),
Student(id: "aa2", name: "Tommy", gradeLevel: 11),
Student(id: "aa3", name: "Susy", gradeLevel: 10),
Student(id: "aa4", name: "Billy", gradeLevel: 12),
Student(id: "aa5", name: "Jimmy", gradeLevel: 12),
Student(id: "aa6", name: "Johnny", gradeLevel: 10),
]
}
}
struct ContentView: View {
@ObservedObject var students = GetStudents()
var body: some View {
VStack {
Text("Total Students: \(self.getTotal())")
// Here is where I'm stuck, need total per gradeLevel derived from array
Text("Total Per Grade Level")
// Grade10 2
// Grade11 1
// Grade12 3
List {
ForEach(students.items) { student in
HStack {
Text("Name: \(student.name)")
Spacer()
Text("Grade: \(student.gradeLevel)")
}
}
}
}
}
private func getTotal() -> Int {
return self.students.items.count
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Upvotes: 0
Views: 56
Reputation: 1414
Here is your class fully updated to display the count of students by grade in your UI:
import SwiftUI
struct Student: Identifiable {
let id: String
let name: String
let gradeLevel: Int
}
class GetStudents: ObservableObject {
@Published var items = [Student]()
@Published var grouped = Dictionary<Int, [Student]>()
init() {
self.items = [
Student(id: "aa1", name: "Bobby", gradeLevel: 12),
Student(id: "aa2", name: "Tommy", gradeLevel: 11),
Student(id: "aa3", name: "Susy", gradeLevel: 10),
Student(id: "aa4", name: "Billy", gradeLevel: 12),
Student(id: "aa5", name: "Jimmy", gradeLevel: 12),
Student(id: "aa6", name: "Johnny", gradeLevel: 10),
]
self.grouped = Dictionary(grouping: self.items, by: { (element: Student) in
return element.gradeLevel
})
// for (k,v) in self.grouped {
// print("grade: \(k)")
// print("items per grade: \(v.count)")
// }
}
}
struct ContentView: View {
@ObservedObject var students = GetStudents()
var body: some View {
let keys = students.grouped.map{$0.key}
let values = students.grouped.map {$0.value}
return VStack {
Text("Total Students: \(self.getTotal())")
// Text("Total Per Grade Level")
List {
ForEach(keys.indices) {index in
HStack {
Text(String("Students in Grade \(keys[index])"))
Spacer()
Text("Total: \(values[index].count)")
}
}
ForEach(students.items) { student in
HStack {
Text("Name: \(student.name)")
Spacer()
Text("Grade: \(student.gradeLevel)")
}
}
}.listStyle(GroupedListStyle())
}
}
private func getTotal() -> Int {
return self.students.items.count
}
}
Upvotes: 2