Ruby on rails 基于嵌套散列的Ruby求和
如何从以下数组中返回总分、笔划和回合数Ruby on rails 基于嵌套散列的Ruby求和,ruby-on-rails,ruby,Ruby On Rails,Ruby,如何从以下数组中返回总分、笔划和回合数 players = [{"Angel Cabrera"=>{"score"=>2, "strokes"=>146, "rounds"=>3}}, {"Jason Day"=>{"score"=>1, "strokes"=>145, "rounds"=>3}}, {"Bryson DeChambeau"=>{"score"=>0, "strokes"=>144, "rounds"=>
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
使用此代码:
@total= 0
players.each do |x|
a= x.values[0]
if a.class == Hash
@total += a["strokes"]
end
end
puts @total
这里有三种方法 使用使用块的形式来确定合并的两个哈希中存在的键的值
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!
)使用块{u124;,o,v | o+v}
)来确定两个哈希中存在的键的值。第一个块变量(未使用,因此可由局部变量\uu
表示)是键,第二个(o
,表示“旧”)是h
中键的值,第三个(n
,表示“新”)是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
求和值,然后转换为哈希值
players.map { |g| g.first.last }.
compact.
each_with_object(Hash.new(0)) { |g,h| g.keys.each { |k| h[k] += g[k] } }
如果您使用的是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
开始)包括:
这里有三种方法 使用使用块的形式来确定合并的两个哈希中存在的键的值
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!
)使用块{u124;,o,v | o+v}
)来确定两个哈希中存在的键的值。第一个块变量(未使用,因此可由局部变量\uu
表示)是键,第二个(o
,表示“旧”)是h
中键的值,第三个(n
,表示“新”)是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
求和值,然后转换为哈希值
players.map { |g| g.first.last }.
compact.
each_with_object(Hash.new(0)) { |g,h| g.keys.each { |k| h[k] += g[k] } }
如果您使用的是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
开始)包括:
如果没有为您提供对象
玩家
,则最好将其表示为哈希:{“Angel Cabrera”=>{“score”=>2,“strokes”=>146,“rounds”=>3},…}
。您应该解释如何处理包含nil
值的players
元素。我假设它们将被跳过,但最初没有注意到孤零零的nil
,这导致了我的代码中的一个错误。如果没有给对象players
,那么最好将其表示为散列:{“Angel Cabrera”=>{“score”=>2,“strokes”=>146,“rounds”=>3},
。您应该解释如何处理包含nil
值的players
元素。我假设它们将被跳过,但最初没有注意到孤零零的nil
,这导致了我的代码中的错误。谢谢,这个解释真的非常有用!谢谢,这个解释真的非常有用!