如何从数组中求平均值?

如果我有一个数组:

[0,4,8,2,5,0,2,6]

平均得到3.375。


当前回答

让我在竞争中引入一些可以解决零除问题的东西

a = [1,2,3,4,5,6,7,8]
a.reduce(:+).try(:to_f).try(:/,a.size) #==> 4.5

a = []
a.reduce(:+).try(:to_f).try(:/,a.size) #==> nil

但是,我必须承认,“try”是一个Rails助手。但你可以很容易地解决这个问题:

class Object;def try(*options);self&&send(*options);end;end
class Array;def avg;reduce(:+).try(:to_f).try(:/,size);end;end

顺便说一句:我认为空列表的平均值为零是正确的。零的平均值是零,不是0。这就是预期行为。但是,如果您更改为:

class Array;def avg;reduce(0.0,:+).try(:/,size);end;end

空数组的结果不会像我预期的那样是一个异常,而是返回NaN…我在Ruby中从未见过这种情况。;-)似乎是Float类的特殊行为…

0.0/0 #==> NaN
0.1/0 #==> Infinity
0.0.class #==> Float

其他回答

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

它并不是纯粹的功能性的。 我们需要一个变量来计算。最后的尺寸。

为了从函数上解决这个问题我们需要关注两个 值:所有元素的和,以及元素的个数。

[5, 6, 7, 8].inject([0.0,0]) do |r,ele|
    [ r[0]+ele, r[1]+1 ]
end.inject(:/)
=> 6.5   

Santhosh改进了这个解决方案:不是参数r是一个数组,我们可以使用解构立即将它分解为两个变量

[5, 6, 7, 8].inject([0.0,0]) do |(sum, size), ele| 
   [ sum + ele, size + 1 ]
end.inject(:/)

如果你想看看它是如何工作的,添加一些看跌期权:

[5, 6, 7, 8].inject([0.0,0]) do |(sum, size), ele| 
   r2 = [ sum + ele, size + 1 ]
   puts "adding #{ele} gives #{r2}"
   r2
end.inject(:/)

adding 5 gives [5.0, 1]
adding 6 gives [11.0, 2]
adding 7 gives [18.0, 3]
adding 8 gives [26.0, 4]
=> 6.5

我们也可以使用结构体而不是数组来包含sum和count,但我们必须先声明结构体:

R=Struct.new(:sum, :count)
[5, 6, 7, 8].inject( R.new(0.0, 0) ) do |r,ele|
    r.sum += ele
    r.count += 1
    r
end.inject(:/)

我认为最简单的答案是

list.reduce(:+).to_f / list.size

你可以试试下面的方法:

a = [1,2,3,4,5]
# => [1, 2, 3, 4, 5]
(a.sum/a.length).to_f
# => 3.0
[1,2].tap { |a| @asize = a.size }.inject(:+).to_f/@asize

简短,但使用实例变量