如何从数组中求平均值?
如果我有一个数组:
[0,4,8,2,5,0,2,6]
平均得到3.375。
如何从数组中求平均值?
如果我有一个数组:
[0,4,8,2,5,0,2,6]
平均得到3.375。
当前回答
你可以试试下面的方法:
a = [1,2,3,4,5]
# => [1, 2, 3, 4, 5]
(a.sum/a.length).to_f
# => 3.0
其他回答
让我在竞争中引入一些可以解决零除问题的东西
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
class Array
def sum
inject( nil ) { |sum,x| sum ? sum+x : x }
end
def mean
sum.to_f / size.to_f
end
end
[0,4,8,2,5,0,2,6].mean
您可以根据需要选择以下解决方案之一。
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
这个方法很有用。
def avg(arr)
val = 0.0
arr.each do |n|
val += n
end
len = arr.length
val / len
end
p avg([0,4,8,2,5,0,2,6])
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