我试图得到一个新的数组哈希值,它会列出每个:在数组(e)的哈希值中只提供一次的名称,该值应该是总得分,它应该是相同的得分总和:数组中的名称(e)。
e = [
{:name => "Oyster", :score => 1000},
{:name => "Tiger", :score => 2000},
{:name => "Frog", :score => 2300},
{:name => "Frog", :score => 1220},
{:name => "Tiger", :score => 200},
{:name => "Frog", :score => 1000},
{:name => "Oyster", :score => 2000},
{:name => "Frog", :score => 300},
{:name => "Monkey", :score => 500},
{:name => "Oyster", :score => 3300}
]
我搜索了谷歌的“哈希数组红宝石”和红宝石的文档,但还没有得到任何非常有用的信息。
我尝试通过执行以下操作来解决此问题:
f = e.map{|t|t[:name]}.uniq
n = Hash[f.map{|v|[v,0]}]
result = n.map{|key, value|e.map{|t| if key == t[:name]; n[key] += t[:score].to_i end}}
但结果是
[[1000, nil, nil, nil, nil, nil, 3000, nil, nil, 6300], [nil, 2000, nil, nil, 2200, nil, nil, nil, nil, nil], [nil, nil, 2300, 3520, nil, 4520, nil, 4820, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, 500, nil]]
它与我的期望完全不同。 如果我们想要达到非常整洁的结果,我们应该做些什么。
答案 0 :(得分:0)
您可以使用group_by
按照:name
对哈希值进行分组,然后使用:score:
和reduce
对merge
值进行求和,如下所示:
e.group_by { |h| h[:name] }.map do |_, v|
v.reduce do |acc, h|
acc.merge(h) { |k, ov, nv| k == :name ? ov : ov + nv }
end
end
#=> [{:name=>"Oyster", :score=>6300}, {:name=>"Tiger", :score=>2200}, {:name=>"Frog", :score=>4820}, {:name=>"Monkey", :score=>500}]
说明:
group_by { |h| h[:name] }
按名称对所有哈希值进行分组,产生如下内容:
{
"Oyster"=>[
{:name=>"Oyster", :score=>1000},
{:name=>"Oyster", :score=>2000},
{:name=>"Oyster", :score=>3300}
],
"Tiger"=>[...]
}
.map
迭代生成的哈希,忽略分组键(_
变量)并仅使用值(v
变量,其中包含分组哈希数组)到将每个哈希的得分相加(见下一步)。
reduce
通过将数组中的所有哈希值合并在一起来对score
的值进行求和(acc
是累积的值/哈希值h
1}}是迭代的当前值/哈希)。请注意,merge
与块一起使用,而不是替换重复键的值(如没有块的merge
),它将使用块中的代码替换其值: / p>
k
是要合并的哈希的当前密钥。ov
是给定密钥的旧值(即acc
哈希的值)。nv
是给定密钥的新值(即h
哈希的值)。因此,在通过name
对哈希进行分组之后,它会迭代每组哈希值并将它们合并为一个哈希值,首先评估当前密钥是否为:name
,如果是,则保留旧密码值(例如"Oyster"
),否则(例如:score
)它会将旧值与新值相加,并将score
的值替换为该结果,累积每次迭代的值。
答案 1 :(得分:0)
我知道这篇文章已经有了一个接受的答案,但是如果你不希望结果是一个哈希数组,只想得到给定名称的给定分数,你可以:
e.inject({}) do |totals, current|
totals[current[:name]] = (totals[current[:name]] || 0) + current[:score]
totals
end
#=> {"Oyster"=>6300, "Tiger"=>2200, "Frog"=>4820, "Monkey"=>500}
答案 2 :(得分:0)
试试这个:
new_array = []
e.each{|h| new_array << { h[:name] => h[:score]} }
new_array.inject{|name, score| name.merge( score ){|k, old_v, new_v| old_v + new_v}}
#=> {"Oyster"=>6300, "Tiger"=>2200, "Frog"=>4820, "Monkey"=>500}
答案 3 :(得分:0)
您可以构建使用Hash::new创建的哈希值,默认值为零(有时称为计算哈希值),然后将哈希值转换为哈希值数组。有关详细信息,请参阅文档。
#calendar li:hover > .date {
text-decoration: underline;
}