2013-04-02 9 views
22

के रूप में हैश वस्तुओं की सरणी में कनवर्ट एक क्षेत्र के साथ मैं ऑब्जेक्ट की श्रृंखला है:कुंजी

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

और मैं कुंजी के रूप में id और वस्तुओं मूल्यों के रूप में के साथ एक हैश में इस परिवर्तित करना चाहते हैं । अभी मैं यह इतना पसंद करते हैं, लेकिन मैं जानता हूँ कि वहाँ एक बेहतर तरीका है:

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

उम्मीद उत्पादन:

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

@SergioTulentsev, मैं कम से [Enumerable # group_by] (http देख रहा था: // www। ruby-doc.org/core-1.9.3/Enumerable.html#method-i-group_by) और यह लगभग वही था जो मैं ढूंढ रहा हूं। मैंने सोचा कि मूल्यों के लिए सरणी बनाने के बजाय इसका एक संस्करण है, यह अधिक आक्रामक है और केवल एक मान रखता है। – Kostas

उत्तर

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

जब रेल (जो आपके कोड की तरह दिखता है) का उपयोग कर, ActiveSupport Enumerable#index_by प्रदान करता है:

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

मैं व्यक्तिगत रूप से 'मैश' रास्ता पसंद करता हूं 'हैश [...]' के बजाय। यह क्लीनर, अधिक रूबी की तरह पढ़ा। – Kostas

+1

मेरा मानना ​​है कि आपकी रूबी> = 2.1 को थोड़ा सुधार की आवश्यकता है, आप चाहते हैं .to_h नहीं .to_a उदा। 'उपयोगकर्ता = User.all.map {| u | [u.id, u]} .to_h' – Tron

4

आप each_with_object बजाय reduce का उपयोग करके एक थोड़ा बेहतर कोड मिलेगा ।

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

क्या हम इंजेक्ट/प्रत्येक_with_object/हैश/मैश पथ फिर से जा रहे हैं? :-) http://bugs.ruby-lang.org/issues/show/666 – tokland

+0

@ टोकलैंड: हाँ, जब मैंने आपकी टिप्पणी देखी तो मेरे सिर में यह पहला विचार था :) –