2013-04-02 15 views
22

bis Hash Ich habe ein Array von Objekten:mit einem Feld als Schlüssel

[ 
    #<User id: 1, name: "Kostas">, 
    #<User id: 2, name: "Moufa">, 
    ... 
] 

Und ich will wandeln diese in eine Hash mit dem id als Schlüssel und die Objekte als Werte . Im Moment mache ich es wie so aber ich wissen, dass es einen besseren Weg:

users = User.all.reduce({}) do |hash, user| 
    hash[user.id] = user 
    hash 
end 

Die erwartete Ausgabe:

{ 
    1 => #<User id: 1, name: "Kostas">, 
    2 => #<User id: 2, name: "Moufa">, 
    ... 
} 
+0

@SergioTulentsev, ich war auf der Suche auf [Enumerable # group_by] (http: // www. ruby-doc.org/core-1.9.3/Enumerable.html#method-i-group_by) und es war fast, was ich suche. Ich dachte nur, es gibt eine Version davon, anstatt Arrays für Werte zu erstellen, ist es aggressiver und behält nur einen Wert. – Kostas

Antwort

44
users_by_id = User.all.map { |u| [u.id, u] }.to_h 

Bei der Verwendung von Rails (die Ihr Code wie folgt aussieht), bietet Active Enumerable#index_by:

users_by_id = User.all.index_by(&:id) 
+0

Ich persönlich bevorzuge den 'Mash' Weg anstatt der 'Hash [...]' one. Es las sauberer, mehr Rubinartig. – Kostas

+1

Ich glaube, Ihr Ruby> = 2.1 braucht eine leichte Korrektur, Sie wollen .to_h nicht .to_a z. 'users = User.all.map {| u | [u.id, du]} .to_h' – Tron

4

Sie werden einen etwas besseren Code erhalten, indem Sie each_with_object statt reduce .

users = User.all.each_with_object({}) do |user, hash| 
    hash[user.id] = user 
end 
+0

Werden wir wieder den inject/each_with_object/Hash/mash Pfad gehen? :-) http://bugs.ruby-lang.org/issues/show/666 – tokland

+0

@tokland: Ja, das war der erste Gedanke in meinem Kopf, als ich deinen Kommentar gesehen habe :) –

Verwandte Themen