如何从数组中求平均值?
如果我有一个数组:
[0,4,8,2,5,0,2,6]
平均得到3.375。
如何从数组中求平均值?
如果我有一个数组:
[0,4,8,2,5,0,2,6]
平均得到3.375。
当前回答
arr = [0,4,8,2,5,0,2,6]
average = arr.inject(&:+).to_f / arr.size
# => 3.375
其他回答
试试这个:
arr = [5, 6, 7, 8]
arr.inject{ |sum, el| sum + el }.to_f / arr.size
=> 6.5
请注意.to_f,它可以避免整数除法带来的任何问题。你还可以:
arr = [5, 6, 7, 8]
arr.inject(0.0) { |sum, el| sum + el } / arr.size
=> 6.5
您可以像另一位评论者建议的那样将其定义为Array的一部分,但您需要避免整数除法,否则您的结果将是错误的。而且,这并不适用于所有可能的元素类型(显然,平均值只适用于可以求平均值的东西)。但如果你想走这条路,可以用这个:
class Array
def sum
inject(0.0) { |result, el| result + el }
end
def mean
sum / size
end
end
如果您以前没有见过inject,那么它并没有看起来那么神奇。它遍历每个元素,然后对其应用累加器值。然后将累加器传递给下一个元素。在本例中,累加器只是一个反映之前所有元素之和的整数。
编辑:评论者戴夫·雷提出了一个很好的改进。
编辑:评论者格伦·杰克曼的提议,使用arr.inject(:+)。To_f也很好,但如果你不知道发生了什么,可能有点太聪明了。:+是一个符号;当传递给inject时,它对每个元素对累加器值应用由符号命名的方法(在本例中为加法操作)。
您可以根据需要选择以下解决方案之一。
Bruteforce
[0,4,8,2,5,0,2,6].sum.to_f / [0,4,8,2,5,0,2,6].size.to_f
=> 3.375
方法
def avg(array)
array.sum.to_f / array.size.to_f
end
avg([0,4,8,2,5,0,2,6])
=> 3.375
猴子打补丁
class Array
def avg
sum.to_f / size.to_f
end
end
[0,4,8,2,5,0,2,6].avg
=> 3.375
但我不建议对Array类进行猴子补丁,这种做法是危险的,可能会对您的系统造成不良影响。
为了我们的好处,ruby语言提供了一个很好的特性来克服这个问题,即Refinements,这是一种安全的方法来对ruby进行monkey补丁。
为了简化,使用细化,您可以猴子修补数组类,并且更改将只在使用细化的类范围内可用!:)
您可以在您正在处理的类中使用细化,并且您已经准备好了。
细化
module ArrayRefinements
refine Array do
def avg
sum.to_f / size.to_f
end
end
end
class MyClass
using ArrayRefinements
def test(array)
array.avg
end
end
MyClass.new.test([0,4,8,2,5,0,2,6])
=> 3.375
比.inject更快的解决方案是:
sum(0.0)/arr.size
参见这篇文章参考:https://andycroll.com/ruby/calculate-a-mean-average-from-a-ruby-array/
a = [0,4,8,2,5,0,2,6]
sum = 0
a.each { |b| sum += b }
average = sum / a.length
为了让公众开心,还有另一个解决方案:
a = 0, 4, 8, 2, 5, 0, 2, 6
a.reduce [ 0.0, 0 ] do |(s, c), e| [ s + e, c + 1 ] end.reduce :/
#=> 3.375