коллег по обмену.Недавно я познакомился с swift
, выполнив несколько тривиальных упражнений, и столкнулся с тем, где нужно вычислять статистику.Цель состояла в том, чтобы вычислить среднее (сумма всех элементов, деленная на количество) для массива чисел.Я решил воспользоваться наиболее известным способом решения этой проблемы и определил расширение для коллекции с помощью функции, которая возвращает числовое значение:
//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
Приведенный выше код работает без проблем.Но я хочу иметь возможность применять mean()
к любой последовательности чисел (числа с плавающей запятой, двойные числа и т. Д.), Поэтому попытайтесь:
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)!
}
}
Это позволит получить результат из любого числового массива:
var array1: [Float] = ...
var array2: [UInt] = ...
var array3: [Int8] = ... //nutty case
Но компиляция завершается неудачно с сообщением, в котором говорится, что, поскольку значения в этой коллекции могут быть другого конкретного типа, невозможно вызвать оператор деления из-за строгой типизации swift
.Таким образом, единственная возможность реализовать необходимую функциональность - это расширить все конкретные типы, работающие с числами (Int, UInt, UInt8, ...), что является надежной вещью (их около 20).Учитывая большие возможности абстракции swift
с расширениями, возможно ли:
extension Collection where Adopter: HomogeneousCollection { ... }
Кроме того, некоторые типы не могут быть большими числами: Int8 может содержать до 256 чисел, поэтому набор [Int8]
может дать правильный результат, только если имеется менее 128 элементов, в противном случае произойдет деление на nil
.
Итак, я спрашиваю, как лучше всего объявить функцию для вычисления среднего для однородного последовательного набора?Кроме того, как бы вы решили для случая, когда коллекция пуста?