19

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この場合01、 、およびには 3 つの異なる値があることに気付くでしょう。ここで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}
  ]
} 

したがって、これらの例の配列が非常に大きいことはわかっていますが、私が考えているよりも単純な問題かもしれないと思います

したがって、基本的に、ハッシュの各配列はそのtypeキーの値によってグループ化され、各タイプの配列を含むハッシュとして返されます。ヘルプは本当に役に立ちます。役立つヒントだけでも大歓迎です。

4

4 に答える 4

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

または、シンボルキーが必要な場合は、

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

これは、「基本的に、ハッシュの各配列はそのタイプ key の値によってグループ化され、タイプごとの配列を持つハッシュとして返される」ことを最もよく表していると思い:typeます。

于 2011-10-06T03:44:51.750 に答える
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
于 2011-10-06T03:39:25.730 に答える
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

注: ここではハッシュ キーが少し異なります。型の値をキーとして直接使用しました。

例のようにハッシュキーが必要な場合は、コメントアウトされた行を追加できます。


PS: Tapio のソリューションを見たところです。非常に素晴らしく、短いです。Ruby >= 1.9 でのみ動作することに注意してください。

于 2011-10-06T03:34:34.380 に答える
2

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}
于 2015-09-03T11:19:50.163 に答える