Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何计算数组中对象的平均值?_Ruby_Average - Fatal编程技术网

Ruby 如何计算数组中对象的平均值?

Ruby 如何计算数组中对象的平均值?,ruby,average,Ruby,Average,假设我有这样一个数组: [ { "player_id" => 1, "number_of_matches" => 2, "goals" => 5 }, { "player_id" => 2, "number_of_matches" => 4, "goals" => 10 } ] 我想知道所有球员每场比赛的平均进球数,

假设我有这样一个数组:

[
  {
    "player_id"         => 1,
    "number_of_matches" => 2,
    "goals"             => 5
  },
  {
    "player_id"         => 2,
    "number_of_matches" => 4,
    "goals"             => 10
  }
]
我想知道所有球员每场比赛的平均进球数,不是每个球员的平均进球数,而是总平均进球数


我想用
。每个
,存储每个平均值,最后将它们全部相加,除以我拥有的球员数量。然而,我正在寻找一种Ruby/单行程序的方法来实现这一点

根据要求,一个班轮:

avg = xs.map { |x| x["goals"].to_f / x["number_of_matches"] }.reduce(:+) / xs.size
更具可读性的代码段:

goals, matches = xs.map { |x| [x["goals"], x["number_of_matches"]] }.transpose 
avg = goals.reduce(:+).to_f / matches.reduce(:+) if goals
编辑:重命名键和块参数以减少字符数。给那些关心的人

首先,如果要使用字符串作为键,则键需要使用
=>


reduce
将对数组进行迭代,并将每个玩家的平均值相加,最后将结果除以玩家总数。括号中的“0”是您的起始编号,表示对tokland的答案稍加修改后的
reduce

items.map{|e| e.values_at("goals", "number_of_matches")}.transpose.map{|e| e.inject(:+)}.instance_eval{|goals, matches| goals.to_f/matches}

要缩短字符串,请将
“匹配数”重命名为
“匹配数”


您可能需要修复数组/哈希,使其实际上是有效的Ruby。让我编辑一下。一行程序很有趣,但在我看来常常被高估。我认为要求一个优雅而干净的解决方案比要求一行程序要好。@Andrew:同意,特别是因为这似乎不是一个可以在一个libe中优雅地解决的问题。@AndrewMarshall你是对的。在制定此类问题时,我会考虑到这一点,以避免答案中出现混淆。凯尔:在一行中这样做会要求代码重复或结果不准确。尼克拉斯:代码重复?请解释我的解决方案是如何重复代码的?它对数组进行一次遍历并产生结果。@Kyle:我说的是一个或多个不准确的结果,就像你的解决方案,它总结了单个除法错误。如果有的话,您必须使用
Rational
。一个线性解决方案将导致对大数字的不准确结果,请查看我的variant@Kyle:只需用分号替换每个换行符。瞧,一行。
arr.map{p|p[:goals]。to|f/p[:number of_matches]}.reduce(:+)/arr.size
会稍微短一点(并且不会溢出代码div)。在一行中的93个字符中,只有3个是空格,在操作符周围多加几个将使其可读性更强。Niklas:您正在映射然后减少,因此,当只需要一个过程时,在数组上迭代两次。@Kyle:是的,但是不适合屏幕的一行不是一行。通常代码应该在第80列左右换行。如果性能是一个问题,人们可能不会选择Ruby来做这项工作。另外,这两种解决方案都是
O(n)
,因此这不是一个“真正的”算法差异。嘿,这是
实例评估的一个很好的技巧(
:)不过,我不希望在生产代码中看到这一点:P
items.map{|e| e.values_at("goals", "number_of_matches")}.transpose.map{|e| e.inject(:+)}.instance_eval{|goals, matches| goals.to_f/matches}
a = [
  {"player_id":1 , "matches":2, "goals": 5}, 
  {"player_id":2 , "matches":4, "goals": 10}
]

a.reduce([0,0]){|sum,h|[sum.first+h["goals"],sum.last+h["matches"]]}.reduce{|sum,m|sum.to_f/m}
#=> 2.5