Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making my function calculate average of array Swift

I want my function to calculate the average of my Double type array. The array is called "votes". For now, I have 10 numbers.

When I call the average function to get the average of the array votes, it doesn't work.

Here's my code:

var votes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  func average(nums: Double...) -> Double {     var total = 0.0     for vote in votes {         total += vote     }     let votesTotal = Double(votes.count)     var average = total/votesTotal     return average }  average[votes] 

How do I call the average here to get the average?

like image 532
Lukesivi Avatar asked Feb 02 '15 22:02

Lukesivi


People also ask

How do you find the average of an array in Swift?

It returns the number of elements present in the array. We know that average is calculated as the sum of elements divided by the number of elements. So let us divide the sum by length to get the average as result and print it. Here, we have converted the types of sum and length to Double to get the result in decimal.

How do you find the average of an array?

Simple approach to finding the average of an array We would first count the total number of elements in an array followed by calculating the sum of these elements and then dividing the obtained sum by the total number of values to get the Average / Arithmetic mean.

How do you find the average of an array using a for each loop?

Example 1 to calculate the average using arrays First, create an array with values and run. the for loop to find the sum of all the elements of the array. Finally, divide the sum with the length of the array to get the average of numbers.

How do you find the average of two arrays?

If you want the avg of all numbers in both arrays, add them all up and divide by 8. If you want to get the avg of both arrays at a certain place add the values at that place in both arrays and divide by 2.


2 Answers

You should use the reduce method to sum your sequence elements as follow:

Xcode Xcode 10.2+ • Swift 5 or later

extension Sequence where Element: AdditiveArithmetic {     /// Returns the total sum of all elements in the sequence     func sum() -> Element { reduce(.zero, +) } } 

extension Collection where Element: BinaryInteger {     /// Returns the average of all elements in the array     func average() -> Element { isEmpty ? .zero : sum() / Element(count) }     /// Returns the average of all elements in the array as Floating Point type     func average<T: FloatingPoint>() -> T { isEmpty ? .zero : T(sum()) / T(count) } } 

extension Collection where Element: BinaryFloatingPoint {     /// Returns the average of all elements in the array     func average() -> Element { isEmpty ? .zero : sum() / Element(count) } } 

let votes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] let votesTotal = votes.sum()                       // 55 let votesAverage = votes.average()                 // 5 let votesDoubleAverage: Double = votes.average()   // 5.5 

If you need to work with Decimal types its total sum it is already covered by the AdditiveArithmetic protocol extension method, so you only need to implement the average:

extension Collection where Element == Decimal {     func average() -> Decimal { isEmpty ? .zero : sum() / Decimal(count) } } 


If you need to sum a certain property of a custom structure we can extend Sequence and create a method that takes a KeyPath as argument to calculate its sum:

extension Sequence  {     func sum<T: AdditiveArithmetic>(_ predicate: (Element) -> T) -> T {         reduce(.zero) { $0 + predicate($1) }     } } 

Usage:

struct User {     let name: String     let age: Int }  let users: [User] = [     .init(name: "Steve", age: 45),     .init(name: "Tim", age: 50)]  let ageSum = users.sum(\.age) // 95 

And extend collection to calculate its average:

extension Collection {     func average<T: BinaryInteger>(_ predicate: (Element) -> T) -> T {         sum(predicate) / T(count)     }     func average<T: BinaryInteger, F: BinaryFloatingPoint>(_ predicate: (Element) -> T) -> F {         F(sum(predicate)) / F(count)     }     func average<T: BinaryFloatingPoint>(_ predicate: (Element) -> T) -> T {         sum(predicate) / T(count)     }     func average(_ predicate: (Element) -> Decimal) -> Decimal {         sum(predicate) / Decimal(count)     } } 

Usage:

let ageAvg = users.average(\.age)                 // 47 let ageAvgDouble: Double = users.average(\.age)   // 47.5 
like image 79
Leo Dabus Avatar answered Sep 19 '22 09:09

Leo Dabus


You have some mistakes in your code:

//You have to set the array-type to Double. Because otherwise Swift thinks that you need an Int-array var votes:[Double] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  func average(nums: [Double]) -> Double {      var total = 0.0     //use the parameter-array instead of the global variable votes     for vote in nums{         total += Double(vote)     }      let votesTotal = Double(nums.count)     var average = total/votesTotal     return average }  var theAverage = average(votes) 
like image 23
Christian Avatar answered Sep 21 '22 09:09

Christian