如何从数组中求平均值?

如果我有一个数组:

[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/

其他回答

我认为最简单的答案是

list.reduce(:+).to_f / list.size
arr = [0,4,8,2,5,0,2,6]
average = arr.inject(&:+).to_f / arr.size
# => 3.375

我非常喜欢定义一个mean()方法,这样我的代码更有表现力。

默认情况下我通常会忽略nil,这是我定义的

def mean(arr)
  arr.compact.inject{ |sum, el| sum + el }.to_f / arr.compact.size
end

mean([1, nil, 5])
=> 3.0

如果您想保留nils,只需删除两个.compact。

无需重复数组(例如,非常适合一行程序):

[1, 2, 3, 4].then { |a| a.sum.to_f / a.size }

一些顶级解决方案的基准测试(按效率最高的顺序排列):

大阵:

array = (1..10_000_000).to_a

Benchmark.bm do |bm|
  bm.report { array.instance_eval { reduce(:+) / size.to_f } }
  bm.report { array.sum.fdiv(array.size) }
  bm.report { array.sum / array.size.to_f }
  bm.report { array.reduce(:+).to_f / array.size }
  bm.report { array.reduce(:+).try(:to_f).try(:/, array.size) }
  bm.report { array.inject(0.0) { |sum, el| sum + el }.to_f / array.size }
  bm.report { array.reduce([ 0.0, 0 ]) { |(s, c), e| [ s + e, c + 1 ] }.reduce(:/) }
end


    user     system      total        real
0.480000   0.000000   0.480000   (0.473920)
0.500000   0.000000   0.500000   (0.502158)
0.500000   0.000000   0.500000   (0.508075)
0.510000   0.000000   0.510000   (0.512600)
0.520000   0.000000   0.520000   (0.516096)
0.760000   0.000000   0.760000   (0.767743)
1.530000   0.000000   1.530000   (1.534404)

小数组:

array = Array.new(10) { rand(0.5..2.0) }

Benchmark.bm do |bm|
  bm.report { 1_000_000.times { array.reduce(:+).to_f / array.size } }
  bm.report { 1_000_000.times { array.sum / array.size.to_f } }
  bm.report { 1_000_000.times { array.sum.fdiv(array.size) } }
  bm.report { 1_000_000.times { array.inject(0.0) { |sum, el| sum + el }.to_f / array.size } }
  bm.report { 1_000_000.times { array.instance_eval { reduce(:+) / size.to_f } } }
  bm.report { 1_000_000.times { array.reduce(:+).try(:to_f).try(:/, array.size) } }
  bm.report { 1_000_000.times { array.reduce([ 0.0, 0 ]) { |(s, c), e| [ s + e, c + 1 ] }.reduce(:/) } }
end


    user     system      total        real
0.760000   0.000000   0.760000   (0.760353)
0.870000   0.000000   0.870000   (0.876087)
0.900000   0.000000   0.900000   (0.901102)
0.920000   0.000000   0.920000   (0.920888)
0.950000   0.000000   0.950000   (0.952842)
1.690000   0.000000   1.690000   (1.694117)
1.840000   0.010000   1.850000   (1.845623)