2016-06-30 14 views
0

I Ergebnisse meiner Abfrage Karte gruppiert nach organisation_id wie so ein Array von Hashes zu erstellen.Schlüssel in Array von Hashes kombinieren

Das Ergebnis sieht so aus:

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

Für jeden organisation_id es einen separaten Eintrag im Array ist. Ich möchte diese Hashes verschmelzen und verbinden die scores Schlüssel wie so:

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

EDIT

Um die results ich folgende AR verwenden zu erstellen:

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) 

Ein Valuation Modell:

class Valuation < ApplicationRecord 
    belongs_to :membership 
    belongs_to :capability 
end 

A Membership Modell:

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

results Schnipsel:

[{"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

Warum die Eile, um eine Antwort auszuwählen? –

+0

Ihre Frage würde stark verbessert, indem Sie ein Beispiel für "Ergebnisse" geben. –

+0

Cary, siehe letzte Änderung –

Antwort

1

Ich werde für jede Organisation übernehmen: den Namen, taglist und organization_id bleibt gleich. Angenommen

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

, dass result ist Ihre letzte Array von Hashes:

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

Ich glaube, das OP möchte den Code ändern, anstatt Code hinzuzufügen, um den falschen Rückgabewert des vorhandenen Codes zu konvertieren. –

1

Ich glaube, das funktioniert, aber die Daten benötigt werden, um es zu testen.

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 

Dies nutzt die Form Hash#update (aka merge!), die einen Block die Werte des Schlüssels zu bestimmen, verwendet, die in beiden fusionierten Hashes vorhanden sind. Bitte konsultieren Sie das Dokument für den Inhalt der einzelnen Blockvariablen _, o und n.

Verwandte Themen