【问题标题】:How to find average of an array of hashes in Ruby如何在Ruby中找到哈希数组的平均值
【发布时间】:2018-04-09 06:22:28
【问题描述】:

我试图在一个数组中找到几个哈希的平均值,如下所示:

[{"path"=>"/abcd.com", "time"=>0.503},
 {"path"=>"/abcd.com", "time"=>0.765},
 {"path"=>"/abcd.com", "time"=>0.553}]

数组是按路径分组的,我想找出加载这条路径的平均时间。

这是我目前所拥有的:

 averages = grouped_data.each do |array|
   array.each do |hash|
     hash["time"].reduce(:+) \ hash.length
   end 
 end

我认为它不起作用,因为哈希中的时间是浮点数。所以我尝试通过添加总数而不使用reduce来解决这个问题,但total返回0

 averages = grouped_data.each do |array|
   total = 0
   array.each do |hash|
     hash["time"] += total \ hash.length
   end 
   return total
 end

感谢您的帮助。谢谢!

【问题讨论】:

  • (1) 反斜杠在那里做什么? total \ hash.length。 (2) 您的哈希仅包含一个条目。因此,hash.length 将始终为 1。

标签: arrays ruby hash average


【解决方案1】:

试试这个:

array = [{"path"=>"/sale.html", "time"=>0.503}, {"path"=>"/sale.html", "time"=>0.765}, {"path"=>"/sale.html", "time"=>0.553}]
average = array.map { |x| x["time"] }.sum / array.size # 0.6070

你也可以直接在数组上使用sum

average = array.sum { |x| x["time"] } / array.size # 0.6070

【讨论】:

  • 对块使用 sum:array.sum { |x| x["time"] }
  • 它说第一个浮点的未定义方法总和第二个数组的未定义方法总和
  • @ShannonNolan 您是否正在尝试使用不同的哈希数组?我已经对上述数组进行了测试,并且得到了结果。
  • @ShannonNolan 你用的是什么 ruby​​ 版本?
  • @ShannonNolan Enumberable#sum 已添加到 ruby​​ 版本 2.4.0。 (该方法在 ActiveSupport(即通常在 Rails 项目中)中也有很多年了。)除非你有充分的理由不这样做,否则我建议只需将你的 ruby​​ 版本更新到当前最新版本:2.5.1
【解决方案2】:

对您的grouped_data 结构进行了假设,请验证。

grouped_data = [
                [
                 {"path"=>"/sale.html", "time"=>0.503},
                 {"path"=>"/sale.html", "time"=>0.765},
                 {"path"=>"/sale.html", "time"=>0.553}
                ],
                [
                 {"path"=>"/sales.html", "time"=>1.0},
                 {"path"=>"/sales.html", "time"=>1.0},
                 {"path"=>"/sales.html", "time"=>4.0}
                ]
               ]

如果你想要每条路径的平均值:

averages = grouped_data.map do |array|
 array.inject(0) do |sum, hash|
   sum + hash["time"]
   end.fdiv(array.size) 
end

 #=> [0.6070000000000001, 2.0]

或带有路径和平均时间的哈希:

avs = grouped_data.map { |array|
  array.inject({}) { |sum, hash|
    sum.merge(hash) { |k, o, n| k == 'time' ? o + n : o }
  }.map { |k, v| [k, k == 'time' ? v.fdiv(array.size) : v] }.to_h
}

 #=> [{ "path" => "/sale.html",  "time" => 0.6070000000000001 },
 #    { "path" => "/sales.html", "time" => 2.0 }]

【讨论】:

  • 如果这对你有用,我会在需要时添加一点解释。
  • 你试过了吗?给出错误..请发布完整的可运行代码
  • @peter 我推断grouped_data 是一个数组数组,每个数组都填充有哈希值。我只是在等待OP的确认。我可能完全错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多