Я не большой поклонник добавления методов к Enumerable
, так как могут быть нежелательные побочные эффекты. Он также предоставляет методы, действительно специфичные для массива чисел, для любого класса, наследуемого от Enumerable
, что в большинстве случаев не имеет смысла.
Хотя это хорошо для тестов, сценариев или небольших приложений, это опасно для более крупных приложений, поэтому вот альтернатива, основанная на ответе @tolitius, которая уже была идеальной. Это больше для справки, чем что-либо еще:
module MyApp::Maths
def self.sum(a)
a.inject(0){ |accum, i| accum + i }
end
def self.mean(a)
sum(a) / a.length.to_f
end
def self.sample_variance(a)
m = mean(a)
sum = a.inject(0){ |accum, i| accum + (i - m) ** 2 }
sum / (a.length - 1).to_f
end
def self.standard_deviation(a)
Math.sqrt(sample_variance(a))
end
end
И тогда вы используете его как таковой:
2.0.0p353 > MyApp::Maths.standard_deviation([1,2,3,4,5])
=> 1.5811388300841898
2.0.0p353 :007 > a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
=> [20, 23, 23, 24, 25, 22, 12, 21, 29]
2.0.0p353 :008 > MyApp::Maths.standard_deviation(a)
=> 4.594682917363407
2.0.0p353 :043 > MyApp::Maths.standard_deviation([1,2,2.2,2.3,4,5])
=> 1.466628787389638
Поведение такое же, но оно позволяет избежать накладных расходов и рисков при добавлении методов в Enumerable
.