繁体   English   中英

嵌套哈希中的Ruby总和

[英]Ruby sum from nested hash

如何从以下数组中返回总分,笔划和回合?

players = [{"Angel Cabrera"=>{"score"=>2, "strokes"=>146, "rounds"=>3}},
 {"Jason Day"=>{"score"=>1, "strokes"=>145, "rounds"=>3}},
 {"Bryson DeChambeau"=>{"score"=>0, "strokes"=>144, "rounds"=>3}},
 {"Sergio Garcia"=>{"score"=>0, "strokes"=>144, "rounds"=>3}},
 {"Ian Poulter"=>{"score"=>5, "strokes"=>162, "rounds"=>3}},
 {"Vijay Singh"=>nil},
 {"Jordan Spieth"=>{"score"=>-4, "strokes"=>140, "rounds"=>3}}]

我可以通过执行以下操作来中风,但是我知道这不是最好的方法。

  players.each do |x|
    x.values()[0]["strokes"]
  end

给定上面的数组,如何返回笔画的总和?

使用此代码:

@total= 0
players.each do |x|
a= x.values[0]
if a.class == Hash
  @total += a["strokes"]
end
end

puts @total

这是三种方法。

使用采用块的Hash#update形式来确定合并的两个哈希中存在的键的值

players.map { |g| g.first.last }.
        compact.
        each_with_object({}) { |g,h| h.update(g) { |_,o,v| o+v } }
  #=> {"score"=>4, "strokes"=>881, "rounds"=>18}

步骤:

a = players.map { |g| g.first.last }
  #=> [{"score"=> 2, "strokes"=>146, "rounds"=>3},
  #    {"score"=> 1, "strokes"=>145, "rounds"=>3},
  #    {"score"=> 0, "strokes"=>144, "rounds"=>3},
  #    {"score"=> 0, "strokes"=>144, "rounds"=>3},
  #    {"score"=> 5, "strokes"=>162, "rounds"=>3},
  #    nil,
  #    {"score"=>-4, "strokes"=>140, "rounds"=>3}] 
b = a.compact
  #=> [{"score"=> 2, "strokes"=>146, "rounds"=>3},
  #    {"score"=> 1, "strokes"=>145, "rounds"=>3},
  #    {"score"=> 0, "strokes"=>144, "rounds"=>3},
  #    {"score"=> 0, "strokes"=>144, "rounds"=>3},
  #    {"score"=> 5, "strokes"=>162, "rounds"=>3},
  #    {"score"=>-4, "strokes"=>140, "rounds"=>3}] 
b.each_with_object({}) { |g,h| h.update(g) { |_,o,v| o+v } }
  #=> {"score"=>4, "strokes"=>881, "rounds"=>18}    

在这里, Hash#update (又名merge! )使用块{ |_,o,v| o+v } { |_,o,v| o+v } )来确定两个哈希中都存在的键的值。 第一个块变量(未使用,因此可以用局部变量_ )是键,第二个( o ,表示“ old”)是键在h的值,第三个( n ,表示“ new”)是g键的值。

使用计数哈希

players.map { |g| g.first.last }.
        compact.
        each_with_object(Hash.new(0)) { |g,h| g.keys.each { |k| h[k] += g[k] } }

Hash.new(0)创建一个默认值为零的空哈希,由块变量g 这意味着,如果哈希h没有键k ,则h[k]返回默认值(但不会更改哈希)。 h[k] += g[k]扩展为:

h[k] = h[k] + g[k]

如果h没有密钥k ,那么右侧的h[k]因此被0代替。

对值求和,然后转换为哈希

如果您使用的是Ruby v1.9 +,并且确保每个哈希中的键具有相同的顺序,则可以采用的第三种方法如下:

["scores", "strokes", "rounds"].zip(
  players.map { |g| g.first.last }.
          compact.
          map(&:values).
          transpose.
          map { |arr| arr.reduce(:+) }
  ).to_h
  #=> {"scores"=>4, "strokes"=>881, "rounds"=>18}

步骤(从上面的b开始)是:

c = b.map(&:values)
  #=> [[ 2, 146, 3],
  #    [ 1, 145, 3],
  #    [ 0, 144, 3],
  #    [ 0, 144, 3],
  #    [ 5, 162, 3],
  #    [-4, 140, 3]] 
d = c.transpose
  #=> [[  2,   1,   0,   0,   5,  -4],
  #    [146, 145, 144, 144, 162, 140],
  #    [  3,   3,   3,   3,   3,   3]] 
totals = d.map { |arr| arr.reduce(:+) }
  #=> [4, 881, 18]
e = ["scores", "strokes", "rounds"].zip(totals)
  #=> [["scores", 4], ["strokes", 881], ["rounds", 18]]
e.to_h
  #=> {"scores"=>4, "strokes"=>881, "rounds"=>18} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM