簡體   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