2011-04-01 7 views
21

我試圖從模型構建散列。從ActiveRecord模型的集合構建散列

這是我想構建的哈希類型。

{"United Sates" => "us", "United Kingdom" => "uk" .....} 

我已經嘗試了很多方法,現在我只是繞着圈子走。

這只是我一些糟糕的嘗試。

select = Array.new 
countries.each do |country| 
    # select.push({country.name => country.code }) 
    # select[country.name][country.code] 
end 

h = {} 

countries.each do |c| 
    # h[] = {c.name => c.code} 
    # h[] ||= {} 
    # h[][:name] = c.name 
    # h[][:code] = c.code 
    #h[r.grouping_id][:name] = r.name 
    # h[r.grouping_id][:description] = r.description 
end 

請注意一下。

謝謝

+1

一些代碼甚至告訴我們你試過的東西可能會有所幫助。 – 2011-04-01 22:12:25

+0

使用Force ... - 我的意思是使用'pluck'和'to_h' https://stackoverflow.com/a/48836177/1536309 – 2018-02-16 23:15:04

回答

63

下面是一些一行代碼的替代品:

# Ruby 2.1+ 
name_to_code = countries.map{ |c| [c.name,c.code] }.to_h 

# Ruby 1.8.7+ 
name_to_code = Hash[ countries.map{ |c| [c.name,c.code] } ] 

# Ruby 1.8.6+ 
name_to_code = Hash[ *countries.map{ |c| [c.name,c.code] }.flatten ] 

# Ruby 1.9+ 
name_to_code = {}.tap{ |h| countries.each{ |c| h[c.name] = c.code } } 

# Ruby 1.9+ 
name_to_code = countries.to_a.each_with_object({}){ |c,h| h[c.name] = c.code } 

的禮貌@下面上癮的評論:

# Ruby 1.8+ 
name_to_code = countries.inject({}){ |r,c| r.merge c.name=>c.code } 
+0

太棒了。我嘗試了地圖,但沒有成功,但名單很好。 TY – Lee 2011-04-01 23:04:54

+0

@Lee如果'map'選項不起作用,請提供詳細信息。例如,「p countries.class」顯示什麼? – Phrogz 2011-04-02 04:57:51

+0

更緊湊的方式來做同樣的事情--- countries.inject({})do | result,country | result.merge(country.name => visitor.code) end – Addicted 2014-01-20 20:12:59

7

定義國家散列,然後從您的記錄中填充它。

countries_hash = {} 
countries.each do |c| 
    countries_hash[c.name] = c.code 
end 
+0

謝謝道格拉斯。構建塊完美謝謝你。注入陷入我的錯誤。但生病繼續玩。謝謝。 – Lee 2011-04-01 22:23:14

+0

刪除了注射的例子,我的注射液顯然是弱的今天晚上。 – 2011-04-01 22:28:56

+2

我想你想要這樣做以加強你的注射fu:'countries_hash = countries.inject({}){| hsh,c | hsh [c.name] = c.code; hsh}'; ['inject'](http://www.ruby-doc.org/core/classes/Enumerable.html#M001494)將塊的返回值傳遞給下一輪。還有['each_with_object'](http://www.ruby-doc.org/core/classes/Enumerable.html#M001516)'inject'的變體不會遇到這個問題(但注意不同的參數順序):'countries_hash = countries.each_with_object({}){| c,hsh | hsh [c.name] = c.code}'。 – 2011-04-01 22:43:45

20

使用Rails 4,你可以簡單地做:

country_codes = Hash[Country.pluck(:name, :code)] 

我認爲這是最佳的澳洲英語,你不必加載了一堆國家對象,並遍歷它們

on Rails的3摘去方法不允許多個屬性,但你可以這樣做:

country_codes = Hash[Country.connection.select_rows(Country.select('name, code').to_sql)] 
0

我最喜歡的答案,這些天是使用pluckto_h

countries.pluck(:name, :code).to_h 
# => {"United Sates" => "us", "United Kingdom" => "uk" .....} 

扭轉他們,並讓代碼第一

countries.pluck(:code, :name).to_h 
# => {"us" => "United Sates", "uk" => "United Kingdom" .....}