2011-11-23 65 views
1
(3.years.ago.to_date..Date.today).map { |date| [date.month, date.year] }.uniq! 

返回:如何將下列數組轉換爲散列?

[[11, 2008], [12, 2008], [1, 2009], [2, 2009], [3, 2009], [4, 2009], [5, 2009], [6, 2009], [7, 2009], [8, 2009], [9, 2009], [10, 2009], [11, 2009], [12, 2009], [1, 2010], [2, 2010], [3, 2010], [4, 2010], [5, 2010], [6, 2010], [7, 2010], [8, 2010], [9, 2010], [10, 2010], [11, 2010], [12, 2010], [1, 2011], [2, 2011], [3, 2011], [4, 2011], [5, 2011], [6, 2011], [7, 2011], [8, 2011], [9, 2011], [10, 2011], [11, 2011]] 

如何變成一個哈希這種結構:

[ 
    [month => 11, year => 2008], 
    [month => 12, year => 2008], 
    [month => 1, year => 2009], 
    etc 
] 

所以我可以用它喜歡:

foo.first.month # returns 11 
foo.first.year # returns 2008 

回答

2
(3.years.ago.to_date..Date.today).map {|date| {:month => date.month, :year => date.year}} 
=> [{:month=>11, :year=>2008}, {:month=>11, :year=>2008}, {:month=>11, :year=>2008}...] 

但是,這個問題是你不會得到免費的方法。您必須重寫Hash上的method_missing以將密鑰作爲方法提供給您。

class Hash 
    def method_missing(method_name, *args) 
    if key?(method_name) 
     self[method_name] 
    else 
     super 
    end 
    end 
end 
+0

foo.first返回'{:一個月=> 11:年=> 2008}'但foo.first.months回報'NoMethodError:{:month => 11,:year => 2008}的未定義方法'month':Hash'。任何想法爲什麼? –

+0

我已經更新了我的答案。 –

+0

我明白了。爲了避免這個問題。使用關聯數組是否很常見?這是否合理?還是有更好的方法來做到這一點與哈希方法? –

0
require 'openstruct' 
array = (3.years.ago.to_date..Date.today).map { |date| [date.month, date.year] }.uniq 
array.map {|ary| OpenStruct.new([:month, :year].zip(ary))} 
0

這個問題需要作爲您預期的結果是沒有意義的:

你沒有散,你有一個數組的數組...用鍵值對(你按索引訪問數組,而不是按鍵)。但鍵是對不存在的月份和年份對象的引用(我假設你想讓它們成爲字符串或符號)。然後你也想像對象一樣訪問它們而不是散列(例如array.first.month vs array.first[:month])。

但無論如何,你不需要做任何特別的事情,因爲日期對象已經存在月份和年份方法。你只需要一個塊傳遞給uniq告訴它你使用的是什麼標準:

(3.years.ago.to_date..Date.today).to_a.uniq { |date| [date.month, date.year] }