我正在尝试使用这个哈希值数组...
items => [{:name=>"item a", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item b", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item a", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item b", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item c", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item d", :count=>1, :contributors=>["51db6d58bd02861e96000004"]}]
获得如下所示的输出......
items => [{:name=>"item a", :count=>2, :contributors=>["51db6d58bd02861e96000004", "51db6d58bd02861e96000004"]},
{:name=>"item b", :count=>2, :contributors=>["51db6d58bd02861e96000004, 51db6d58bd02861e96000004"]},
{:name=>"item c", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item d", :count=>1, :contributors=>["51db6d58bd02861e96000004"]}]
我希望按名称进行分组并合并计数和贡献者,如上所示。我怎么做? Group_by,减少?有人可以发一个例子吗?
答案 0 :(得分:2)
items = [
{:name=>"item a", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item b", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item a", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item b", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item c", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
{:name=>"item d", :count=>1, :contributors=>["51db6d58bd02861e96000004"]}
]
items.group_by { |h| h[:name] }.map { |key, hs|
{:name => key,
:count => hs.inject(0) { |c, h| c + h[:count] },
:contributors => hs.map { |h| h[:contributors] }
}
}
# => [{:name=>"item a", :count=>2,
# :contributors=>[["51db6d58bd02861e96000004"], ["51db6d58bd02861e96000004"]]},
# {:name=>"item b", :count=>2,
# :contributors=>[["51db6d58bd02861e96000004"], ["51db6d58bd02861e96000004"]]},
# {:name=>"item c", :count=>1, :contributors=>[["51db6d58bd02861e96000004"]]},
# {:name=>"item d", :count=>1, :contributors=>[["51db6d58bd02861e96000004"]]}]
答案 1 :(得分:1)
我最初发布了另一个解决方案,但发现@falsetru已经发布了几乎相同的答案,所以它又回到了绘图板。实际上并不完全,因为对于这类问题,有两种常见的攻击线,所以我接着另一条攻击线。
def combine(items)
items.each_with_object({}) do |g,h|
h.update({ g[:name] => g }) do |k,ov,nv|
{ name: g[:name], count: (ov[:count] + nv[:count]),
contributors: (ov[:contributors] + nv[:contributors]) }
end
end.values
end
这使用Hash#update(又名merge!
)的形式,它采用一个块来确定被合并的两个哈希共享的每个键的值。
注意我允许:count
使1
和:contributors
以外的值具有包含多个值的值(数组)。
combine(items)
#=>[{:name=>"item a", :count=>2,
# :contributors=>["51db6d58bd02861e96000004", "51db6d58bd02861e96000004"]},
# {:name=>"item b", :count=>2,
# :contributors=>["51db6d58bd02861e96000004", "51db6d58bd02861e96000004"]},
# {:name=>"item c", :count=>1, :contributors=>["51db6d58bd02861e96000004"]},
# {:name=>"item d", :count=>1, :contributors=>["51db6d58bd02861e96000004"]}]