dot*_*tty 202 ruby ruby-on-rails
如何从阵列中找到平均值?
如果我有阵列:
[0,4,8,2,5,0,2,6]
Run Code Online (Sandbox Code Playgroud)
平均值会给我3.375.
谢谢!
Joh*_*lla 255
试试这个:
arr = [5, 6, 7, 8]
arr.inject{ |sum, el| sum + el }.to_f / arr.size
=> 6.5
Run Code Online (Sandbox Code Playgroud)
请注意.to_f,您需要避免整数除法的任何问题.你也可以这样做:
arr = [5, 6, 7, 8]
arr.inject(0.0) { |sum, el| sum + el } / arr.size
=> 6.5
Run Code Online (Sandbox Code Playgroud)
您可以将其定义Array为另一个评论者建议的一部分,但您需要避免整数除法,否则您的结果将是错误的.此外,这通常不适用于每种可能的元素类型(显然,平均值仅对可以平均的事物有意义).但是如果你想走那条路,那就用这个:
class Array
def sum
inject(0.0) { |result, el| result + el }
end
def mean
sum / size
end
end
Run Code Online (Sandbox Code Playgroud)
如果你以前没见过inject,那就不像它看起来那么神奇了.它迭代每个元素,然后将累加器值应用于它.然后将累加器传递给下一个元素.在这种情况下,我们的累加器只是一个整数,它反映了所有先前元素的总和.
编辑:评论家戴夫雷提出了一个很好的改进.
编辑:评论者格伦杰克曼的提议,使用arr.inject(:+).to_f,也很好,但如果你不知道发生了什么,也许有点太聪明了.这:+是一个象征; 当传递给inject时,它将符号命名的方法(在本例中为加法运算)应用于累加器值的每个元素.
Cor*_*ook 109
a = [0,4,8,2,5,0,2,6]
a.instance_eval { reduce(:+) / size.to_f } #=> 3.375
Run Code Online (Sandbox Code Playgroud)
不使用的版本instance_eval是:
a = [0,4,8,2,5,0,2,6]
a.reduce(:+) / a.size.to_f #=> 3.375
Run Code Online (Sandbox Code Playgroud)
Den*_*ham 47
我希望Math.average(值),但没有这样的运气.
values = [0,4,8,2,5,0,2,6]
average = values.sum / values.size.to_f
Run Code Online (Sandbox Code Playgroud)
San*_*osh 34
Ruby版本> = 2.4有一个Enumerable#sum方法.
要获得浮点平均值,可以使用Integer#fdiv
arr = [0,4,8,2,5,0,2,6]
arr.sum.fdiv(arr.size)
# => 3.375
Run Code Online (Sandbox Code Playgroud)
对于旧版本:
arr.reduce(:+).fdiv(arr.size)
# => 3.375
Run Code Online (Sandbox Code Playgroud)
最佳解决方案的一些基准测试(以最有效的顺序):
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
无需重复数组(例如,非常适合单行):
[1, 2, 3, 4].then { |a| a.sum.to_f / a.size }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140763 次 |
| 最近记录: |