说我有这个:
[
{ :user_id => 1, :search_id => a},
{ :user_id => 1, :search_id => b},
{ :user_id => 2, :search_id => c},
{ :user_id => 2, :search_id => d}
]
我希望最终得到:
[
{ :user_id => 1, :search_id => [a,b]},
{ :user_id => 2, :search_id => [c,d]}
]
最好的方法是什么?
答案 0 :(得分:7)
[ { :user_id => 1, :search_id => "a"},
{ :user_id => 1, :search_id => "b"},
{ :user_id => 2, :search_id => "c"},
{ :user_id => 2, :search_id => "d"} ] \
.map{ |h| h.values_at(:user_id, :search_id) } \
.group_by(&:first) \
.map{ |k, v| { :user_id => k, :search_id => v.map(&:last) } }
答案 1 :(得分:1)
array.group_by{|x| x[:user_id] }.values.map do |val|
{ user_id: val.first[:user_id],
search_id: val.inject([]){|me, el| me << el[:search_id]} }
end
答案 2 :(得分:0)
首先,我认为这里更清晰的输出结构是允许用户ID为散列键,搜索ID列表为值:
{
1 => [a, b],
2 => [c, d]
}
使用Rails帮助程序可能有一种聪明的方法来获得这种结构,但是手动执行它也不是太糟糕:
output = {}
input.each do |row|
key = row[:user_id]
value = row[:search_id]
output[key] ||= []
output[key] << value
end
答案 3 :(得分:0)
我同意Matchus对数据的表示,并且只想为它建议一个更短的版本(输入是初始数组)。
input.each.with_object(Hash.new {|h,k| h[k] = []}) do |k,o|
o[k[:user_id]] << k[:search_id]
end
编辑:这是Ruby&gt; 1.9
答案 4 :(得分:0)
input.inject({}) do
|m, h| (m[h[:user_id]] ||= []) << h[:search_id]; m
end.inject([]) { |m, (k, v)| m << { :user_id => k, :search_id => v }; m }