2011-10-06 76 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中分割陣列爲多個小數組的最佳方法(