Ruby组按键的值进行散列

Ruby组按键的值进行散列,ruby,mongodb,hash,mongodb-ruby,Ruby,Mongodb,Hash,Mongodb Ruby,我有一个数组,它是由MongoDB执行的map/reduce方法输出的,它看起来像这样: [{"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>299.0}, {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=&

我有一个数组,它是由MongoDB执行的map/reduce方法输出的,它看起来像这样:

[{"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>299.0}, 
{"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>244.0}, 
{"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>1.0, "count"=>204.0}, 
{"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>510.0}, 
{"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>437.0}, 
{"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>469.0}, 
{"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>477.0}, 
{"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>481.0}, 
{"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>401.0}, 
{"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>468.0}, 
{"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>448.0}, 
{"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>485.0}, 
{"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>518.0}] 
您会注意到,
type
有三个不同的值,在本例中,
0
1
2
,现在要做的是根据其
type
键的值对哈希数组进行分组,因此,例如,此数组将以如下方式结束:

{
  :type_0 => [
    {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>299.0}, 
    {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>510.0}, 
    {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>469.0}, 
    {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>481.0}, 
    {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>468.0}, 
    {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>485.0}
  ],

  :type_1 => [
    {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>204.0}
  ],

  :type_10 => [
    {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>244.0}, 
    {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>437.0},
    {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>477.0}, 
    {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>401.0}, 
    {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>448.0}, 
    {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>518.0}
  ]
} 
所以我知道这些示例数组非常大,但我认为这可能是一个比我想象的更简单的问题

因此,基本上每个哈希数组都会根据其
类型
键的值进行分组,然后作为哈希返回,每个类型都有一个数组,任何帮助都会非常有用,即使只是一些有用的提示也会非常感谢。

by_type={}
by_type = {}

a.each do |h|
   type = h.delete("type").to_s
   # type = ("type_" + type ).to_sym

   by_type[ type ] ||= []
   by_type[ type ] << h      # note: h is modified, without "type" key

end
a、 每个都有| h| 类型=h.删除(“类型”)。至 #类型=(“类型+类型”)到符号 按类型[类型]| |=[]
也许是这样的

mangled = a.group_by { |h| h['type'].to_i }.each_with_object({ }) do |(k,v), memo|
    tk = ('type_' + k.to_s).to_sym
    memo[tk] = v.map { |h| h = h.dup; h.delete('type'); h }
end
或者,如果您不关心保留原始数据:

mangled = a.group_by { |h| h['type'].to_i }.each_with_object({ }) do |(k,v), memo|
    tk = ('type_' + k.to_s).to_sym
    memo[tk] = v.map { |h| h.delete('type'); h } # Drop the h.dup in here
end
或者如果你想要符号,你甚至可以

array.group_by {|x| "type_#{x['type']}".to_sym}
我认为这最好地表达了“因此基本上,每个散列数组将根据其类型键的值分组,然后作为散列返回,每个类型都有一个数组”,即使它将
:type
键单独保留在输出哈希中。

groupby
将可枚举项收集到集合中,并根据块的结果进行分组。您不必简单地获取该块中的键值,因此如果您想在这些集合中省略
'type'
,您可以这样做,如:

array.group_by {|x| "type_#{x.delete('type').to_i}".to_sym}
这将完全符合您的要求

高级:这有点超出了问题的范围,但如果要保留原始数组,必须复制其中的每个对象。这将实现以下目的:

array.map(&:dup).group_by {|x| "type_#{x.delete('type').to_i}".to_sym}

为什么不通过{x | x['type']}
a.group_
?因为它不会删除'type'键?我认为这并不重要,不是吗?@Tapio:在他的例子中,他希望在这个过程中从散列中删除“type”键。。。是的,我同意,这并不重要。。group_by()是新的美味佳肴,谢谢+1它不会产生问题中的输出,在Ruby 1中也不起作用。8这将分组,但不会删除响应中的“类型”。我不介意,因为它很简单,但它没有回答这个问题,tbh。可能的重复
array.map(&:dup).group_by {|x| "type_#{x.delete('type').to_i}".to_sym}