0

I want to display an average for all values that are inputted into an Entity. Basically, one would press add on the TableView and a pop up would appear asking for a score, which would then add that “exam” to the tableview. I want to be able to add up all the scores and receive an average for them which i can then add to a label. I’ve tried following some other tutorial but it gives me an error.

https://i.stack.imgur.com/P7exB.jpg https://i.stack.imgur.com/WWITI.jpg

The images above are for context.

var i = 0
var sum = 0

    for i in 0...methodsExam.count {
        let title = methodsExam[i]
        let str : String = title.value(forKey: "score") as! String
        sum = sum + Int(str)!
    }
    let avg = sum/methodsExam.count
    
    averageScore.text = "Average: \(avg)"
aadi sach
  • 51
  • 5

1 Answers1

0

Assuming methodsExam is an array of [MethodsExam] you can change the loop to

var sum = 0.0
for item in methodsExam {
    if let scoreStr = item.score, let score = Double(scoreStr) {
        sum += score
    }
}
let average = sum / Double(methodsExam.count)

I am using Double here for more precision.

This could also be done with a high-order function

let average = methodsExam.reduce(into: 0.0) {
    if let scoreStr = $1.score, let score = Double(scoreStr) { $0 += score }
} / Double(methodsExam.count)

Since we are dividing with the array count we must also check that the array isn't empty to avoid division by 0, so we can put the code into a function and do this

func calculateAverage(_ array: [MethodsExam]) -> Double {
    guard !array.isEmpty else { return 0.0 }

    return  array.reduce(into: 0.0) {
        if let scoreStr = $1.score, let score = Double(scoreStr) { $0 += score }
    } / Double(array.count)
}

One caveat, I assumed that score can be nil because of MethodsExam being an NSManagedObject and not because it will hold nil values. If it indeed can hold nil values then you need to consider what to calculate the average on, all values in the array or only non-nil values.

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52