如何从数组中求平均值?

如果我有一个数组:

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

平均得到3.375。


当前回答

我认为最简单的答案是

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

其他回答

[1,2].tap { |a| @asize = a.size }.inject(:+).to_f/@asize

简短,但使用实例变量

数组添加#平均水平。

我经常做同样的事情,所以我认为用一个简单的平均方法扩展Array类是谨慎的。除了整数、浮点数或小数之类的数字数组之外,它并不适用于任何东西,但当你正确使用它时,它很方便。

我使用Ruby on Rails,所以我把它放在配置/initializers/array中。Rb但是你可以把它放在boot中包含的任何地方,等等。

配置/初始化/ array.rb

class Array

  # Will only work for an Array of numbers like Integers, Floats or Decimals.
  #
  # Throws various errors when trying to call it on an Array of other types, like Strings.
  # Returns nil for an empty Array.
  #
  def average
    return nil if self.empty?

    self.sum.to_d / self.size
  end

end

您可以根据需要选择以下解决方案之一。

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
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.empty? ? nil : a.reduce(:+)/a.size.to_f
=> 3.375

解决除零,整数除法,易于阅读。如果您选择让空数组返回0,则可以轻松修改。

我也喜欢这个变体,但是有点啰嗦。

a = [0,4,8,2,5,0,2,6]
a.empty? ? nil : [a.reduce(:+), a.size.to_f].reduce(:/)
=> 3.375