fellow exchangers. Recently, I was familiarizing myself with swift
by solving some trivial exercises and faced one where statistics should be calculated. The goal was to calculate the mean (sum of all elements divided by amount) for an array of numbers. I decided to follow the best known way to solve this, and defined an extension over a collection with a function that returns a numeric value:
//this is specific case with Integers. Seems bold enought
extension Array where Element == Int {
func mean() -> Double {
var result = 0.0
for i in self {
result += Double(i)
}
return result / Double(self.count)
}
}
[1,2,3,4,5,6,7,8,9].mean() //outputs 5.0
The code above runs without a problem. But I want to be able to apply mean()
to any sequence of numerals (Floats, Doubles, etc), so the try is:
extension Collection where Element: Numeric {
func mean() -> some Numeric {
var result = Element.init(exactly: 0)!
for i in self {
result += i
}
return result / Element.init(exactly: self.count)!
}
}
This would allow to get a result from any numeral array:
var array1: [Float] = ...
var array2: [UInt] = ...
var array3: [Int8] = ... //nutty case
But the compilation fails with a message that says that, because values in that collection can be of a different concrete type, it is not possible to invoke a division operator due to swift
strict typing. So, the only option to implement needed functionality is to extend all concrete types that operate with numbers (Int, UInt, UInt8, ...), which is a robust thing to do (there are ~20 of them). Given swift
's great abstractization possibilities with extensions, is it possible to:
extension Collection where Adopter: HomogeneousCollection { ... }
Also, some types cannot be big numbers: Int8 can hold up to 256 numbers, so a collection of [Int8]
can only give a correct result if there is less than 128 elements, otherwise division by nil
would occur.
So I ask, what is the most appropriate way to declare a function to calculate a mean for a homogeneous sequential collection? Also, how would you solve for a case when collection is empty?