如何在SwiftUI中从数组计算总数,小计和平均值

问题描述 投票:1回答:1

我是SwiftUI的新手,已经被困了几天。

我有一个可识别的无序数组。我在父视图中有一个用于该数组的过滤器,并且该过滤器的值向下传递到了子视图中。

我需要根据数组中一个元素的值对元素进行分组,然后根据每个数组元素中设置的另一个值来计算总数,小计和平均值。

计算需要基于在父视图中设置为true或false的过滤器进行更新。

我通过在ForEach视图内进行计算,在JavaScript(反应)中轻松解决了这个问题,但不知道如何在SwitUI中解决此问题。

非常感谢任何帮助!

struct Student: Identifiable {
    let id: String
    let name: String
    let gradeLevel: Int
    let studyHours: Int
}

class GetStudents: ObservableObject {

    @Published var items = [Student]()

    init() {
        self.items = [
            Student(id: "aa1", name: "Bobby", gradeLevel: 9, studyHours: 2),
            Student(id: "aa2", name: "Sally", gradeLevel: 12, studyHours: 4),
            Student(id: "aa3", name: "Susy", gradeLevel: 11, studyHours: 3),
            Student(id: "aa4", name: "Billy", gradeLevel: 12, studyHours: 5),
            Student(id: "aa5", name: "Jimmy", gradeLevel: 11, studyHours: 1),
            Student(id: "aa6", name: "Johnny", gradeLevel: 10, studyHours: 3),
            Student(id: "aa7", name: "Mikey", gradeLevel: 12, studyHours: 2),
        ]
    }
}

struct StudyTotals: View {

    @ObservedObject var students = GetStudents()

    var onlyUpperClass: Bool

    var studentsFiltered: [Student] {
        switch self.onlyUpperClass {
        case true: return students.items.filter {$0.gradeLevel == 11 || $0.gradeLevel == 12 }
        case false: return students.items
        }
    }

    var body: some View {

        var myArray = getCalcTotals(students: studentsFiltered)

        var rows: Array<String> = []

        return VStack {

            Text("Push Calculated Rows Here??? ")

        }.padding()
    }
}

struct ContentView: View {
    @State private var onlyUpperClass: Bool = false
    var body: some View {
        return VStack {
            StudyTotals(onlyUpperClass: self.onlyUpperClass)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


func getCalcTotals(students: Array<Student>) -> Array<String> {
    let studentArray = students.reduce({ /* here */ })

    var grade: String
    var gradeCount: Int
    var gradeHours: Double? = 0
    var gradeAvg: Double? = 0

    let myArray = ["Count", "Total", "Average"]
    return myArray
}

我需要的是这个:

enter image description here

arrays swift view swiftui
1个回答
0
投票

您可以像在JavaScript中那样计算ForEach中的值

struct StudyTotals: View {

    @ObservedObject var students = GetStudents()

    var onlyUpperClass: Bool

    var studentsFiltered: [Student] {
        switch self.onlyUpperClass {
        case true: return students.items.filter {$0.gradeLevel == 11 || $0.gradeLevel == 12 }
        case false: return students.items
        }
    }

    var body: some View {

        var countTotal = self.studentsFiltered.count
        var hoursTotal = self.studentsFiltered.reduce(0) { $0 + $1.studyHours }

        return List {
            Group {
                HStack {
                    Text("Count")
                    Text("Hours")
                    Text("Avg")
                }
                ForEach(9...12, id: \.self) { gradeLevel -> AnyView in
                    let count = self.studentsFiltered.filter{ $0.gradeLevel ==  gradeLevel }.count
                    let hours = self.studentsFiltered.filter{ $0.gradeLevel ==  gradeLevel }.reduce(0) { $0 + $1.studyHours }
                    let avg = Float(hours) / Float(count)
                    countTotal += count
                    hoursTotal += hours
                    return AnyView(HStack {
                        Text("Grade\(gradeLevel)")
                        Text("\(count)")
                        Text("\(hours)")
                        Text("\(avg)")
                    })
                }
                HStack {
                    Text("TOTALS")
                    Text("\(countTotal)")
                    Text("\(hoursTotal)")
                    Text("\(Float(hoursTotal) / Float(countTotal))")
                }
            }
        }.padding()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.