[英]Get averages from array of arrays
我有一个类似于以下数组的数组:
[["Timmy", "90", "47", "89"], ["Simon", "89", "57", "99"]] (etc)
我需要遍历每个子数组,并求和每个子数组中的数字,并给出每个子数组的平均值。
我不确定如何访问每个号码。 任何帮助,将不胜感激!
这是一个可能的解决方案:
arr = [["Timmy", "90", "47", "89"], ["Simon", "89", "57", "99"]]
averages = arr.map do |name, *nums|
[name, nums.map(&:to_f).inject(:+) / nums.length]
end
# => [["Timmy", 75.33333333333333], ["Simon", 81.66666666666667]]
此解决方案使用ruby的列表推导,因此arr
每个元素都在参数|name, *nums|
的块上运行。 ,将name
设置为数组中的第一个元素,将nums
设置为数组的其余部分(减去name
)。
nums.map(&:to_f).inject(:+)
变为每个字符串以一个浮点数,然后通过元素的数量在分割nums
以创建平均。
有点不同,但变体更快:
arr = [["Timmy", "90", "47", "89"], ["Simon", "89", "57", "99"]]
averages = arr.map do |name, *nums|
[name, nums.inject(0){|acc, el| acc + el.to_f} / nums.length]
end
p averages
# => [["Timmy", 75.33333333333333], ["Simon", 81.66666666666667]]
与最初为0的累加器一起使用inject
。然后将转换为Float的每个数字添加到其中。
基准测试:
require 'benchmark'
arr = [["Timmy", "90", "47", "89"], ["Simon", "89", "57", "99"]]
n = 1_000_000
Benchmark.bm do |x|
x.report("map.inject : ") { n.times do ; arr.map do |name, *nums| ; [name, nums.map(&:to_f).inject(:+) / nums.length] ; end ; end }
x.report("inject(acc): ") { n.times do ; arr.map do |name, *nums|; [name, nums.inject(0){|ac,el| ac +el.to_f} / nums.length]; end ; end }
end
#=> user system total real
#=> map.inject : 2.220000 0.000000 2.220000 ( 2.218477)
#=> inject(acc): 2.030000 0.000000 2.030000 ( 2.031263)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.