2016-06-30 2 views
0

の配列のキーを組み合わせて、私はそうのようなorganisation_idでグループ化されたハッシュの配列を作成するために、私のクエリの結果をマップ:はハッシュ

results.map do |i| 
    { 
    i['organisation_id'] => { 
     name: capability.name, 
     tags: capability.tag_list, 
     organisation_id: i['organisation_id'], 
     scores: {i['location_id'] => i['score']} 
    } 
    } 

capabilityは、マップ外で定義されています。配列内の別のエントリがあるすべてのorganisation_idについては

[{1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{26=>4}}}, {1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{12=>5}}}, {2 => {...}}...]

:よう

結果が見えます。

Valuation.joins(:membership) 
     .where(capability: capability) 
     .select("valuations.id, valuations.score, valuations.capability_id, valuations.membership_id, memberships.location_id, memberships.organisation_id") 
     .map(&:serializable_hash) 

Valuationモデル:私は、次のARを使用resultsを作成するには

[{1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{26=>4, 12=>5}}}, {2=>{...}}... ]

EDIT

:私はこれらのハッシュをマージし、そのようscoresキーを組み合わせるしたいと思います:

class Valuation < ApplicationRecord 
    belongs_to :membership 
    belongs_to :capability 
end 

Membershipモデル:

class Membership < ApplicationRecord 
    belongs_to :organisation 
    belongs_to :location 
    has_many :valuations 
end 

resultsはスニペット:

[{"id"=>1, "score"=>4, "capability_id"=>1, "membership_id"=>1, "location_id"=>26, "organisation_id"=>1}, {"id"=>16, "score"=>3, "capability_id"=>1, "membership_id"=>2, "location_id"=>36, "organisation_id"=>1}, {"id"=>31, "score"=>3, "capability_id"=>1, "membership_id"=>3, "location_id"=>26, "organisation_id"=>2}, {"id"=>46, "score"=>6, "capability_id"=>1, "membership_id"=>4, "location_id"=>16, "organisation_id"=>2}...

+0

なぜ回答を選択するのが急いでいるのですか? –

+0

'results'の例を挙げれば、あなたの質問は大幅に改善されます。 –

+0

Cary、最新の編集を参照してください –

答えて

1

私は組織ごとに仮定します:名前、タグリストとORGANIZATION_IDは同じまま。

your_hash = results.reduce({}) do |h, i| 
    org_id = i['organisation_id'] 
    h[org_id] ||= { 
    name: capability.name, 
    tags: capability.taglist, 
    organisation_id: org_id, 
    scores: {} 
    } 
    h[org_id][:scores][i['location_id']] = i['score'] 
    # If the location scores are not strictly exclusive, you can also just += 
    h 
end 
0

resultはハッシュの最終的な配列であることを、仮定します。

result.each_with_object({}) do |e, obj| 
    k, v = e.flatten 
    if obj[k] 
    obj[k][:scores] = obj[k][:scores].merge(v[:scores]) 
    else 
    obj[k] = v 
    end 
end 
+0

OPは、既存のコードの不正な戻り値を変換するコードを追加するのではなく、コードを変更したいと考えています。 –

1

私は、この作品と考えていますが、データはそれをテストするために必要とされます。

results.each_with_object({}) do |i,h| 
    h.update(i['organisation_id'] => { 
    name: capability.name, 
    tags: capability.tag_list, 
    organisation_id: i['organisation_id'], 
    scores: {i['location_id'] => i['score']}) { |_,o,n| 
     o[:scores].update(n[:score]); o } 
    } 
end.values 

これは、マージされ、両方のハッシュに存在するキーの値を決定するためにブロックを使用して(別名merge!Hash#updateの形態を使用します。各ブロック変数_onの内容については、ドキュメントを参照してください。

関連する問題