2011-11-23 64 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] }