在Rails中,将哈希压缩为嵌套哈希的最佳方法是什么

时间:2011-12-06 17:48:56

标签: ruby-on-rails ruby hash

说我有这个:

[
  { :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]}
]

最好的方法是什么?

5 个答案:

答案 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 }