2011-10-06 74 views
16

哈希值我有一个数组,它由映射输出/减少MongoDB的执行方法,它看起来是这样的:红宝石组通过的关键

[{"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值,在这种情况下012,现在想做的是组数组哈希由价值的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} 
    ] 
} 

所以我知道这些例子阵列真的很大,但我认为它可能比我做出来是

所以基本上哈希值的每个阵列将通过价值进行分组更简单的问题,它的type键,然后作为散列返回,每个类型都有一个数组,任何帮助都会非常有帮助,即使只是一些有用的提示将不胜感激。

+0

可能重复http://stackoverflow.com/questions/5686493/best-way-to-split-arrays -into-multiple-small-arrays-in-ruby) – akostadinov

回答

30
array.group_by {|x| x['type']} 

,或者如果你想要的符号关键的东西,你甚至可以

array.group_by {|x| "type_#{x['type']}".to_sym} 

我想这最好表达“所以基本上每个散列数组将是按其类型键的值分组,然后作为散列返回,每个类型为“,即使它仅将:type键保留在输出散列中。

+2

它不会在问题中产生输出,并且在Ruby 1.8中不起作用 – 2011-10-06 18:21:49

+2

这将分组,但它不会删除响应中的“类型”。我不介意,因为它很简单,但它不回答这个问题,tbh。 – pjammer

2
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 

注:此处略有不同的哈希键,我直接使用的类型值作为关键

如果你必须有哈希键作为你的榜样,你可以添加一个注释行出。


P.S:我刚才看到塔皮奥的解决方案 - 这是非常好的,短!请注意,它只适用于Ruby> = 1.9

+1

为什么不只是'a.group_by {| x | x ['type']}'? –

+0

它不会删除'type'键吗?我不认为这真的很重要,是吗? –

+0

@Tapio:在他的例子中,他期待着沿着哈希的方式将“类型”键从中删除......是的,我同意,并不重要.. group_by()是新的和美味的,谢谢! +1 – Tilo

2

也许这样的事情?

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 
0

group_by收集一个枚举集合,按块的结果分组。你是不是限制在此块简单地拿到钥匙的价值,所以如果你想省略'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} 
的[在Ruby中分割阵列为多个小数组的最佳方法(