从Ruby中的嵌套哈希值返回值

时间:2015-11-27 19:55:06

标签: ruby hash iteration

我想在以下哈希中返回"BBQ"为值的所有假日符号(即:memorial_day:fourth_of_july):

holiday_hash = 
      {
         :winter => {
           :christmas => ["Lights", "Wreath"],
           :new_years => ["Party Hats"]
         },
         :summer => {
           :fourth_of_july => ["Fireworks", "BBQ"]
         },
         :fall => {
           :thanksgiving => ["Turkey"]
         },
         :spring => {
           :memorial_day => ["BBQ"]
         }
       }

这是我的代码:

def all_holidays_with_bbq(holiday_hash)
  holiday_hash.each do |season, holiday|
    season.each do |holiday|
      holiday.each do |supply|
        new_array = []
        if supply = "BBQ"
          new_array << supply.keys
        end
        new_array
      end
    end
  end
end

我的代码返回此错误:

NoMethodError:
        undefined method `each' for :winter:Symbol

谢谢!

2 个答案:

答案 0 :(得分:2)

问题:

您收到此错误:

NoMethodError:
        undefined method `each' for :winter:Symbol

因为您在符号.each上调用season.each do |holiday|,其中season是符号。相反,您应该迭代这样的哈希元素:holiday_hash[season].each do |key, values| . . .

解决方案:

您需要将all_holidays_with_bbq方法更改为以下内容才能解决问题:

def all_holidays_with_bbq(holiday_hash)
  new_array = []
  holiday_hash.keys.each do |season| # iterate over the keys(seasons) in your holiday_hash.
    holiday_hash[season].each do |key, value| # iterate over inner hash where season is the key.            
      new_array << key if value.include? 'BBQ'
    end
  end
  new_array
end

p all_holidays_with_bbq(holiday_hash)
# => [:fourth_of_july, :memorial_day]

答案 1 :(得分:0)

你的问题已经被@KMRakibulIslam回答了,但是我认为这是另一种方式,我觉得它非常像Ruby:

holiday_hash.values.
             flat_map(&:to_a).
             select { |_,a| a.include?("BBQ") }.
             map(&:first)
  #=> [:fourth_of_july, :memorial_day] 

以下是步骤:

a = holiday_hash.values
  #=> [{:christmas=>["Lights", "Wreath"], :new_years=>["Party Hats"]},
  #    {:fourth_of_july=>["Fireworks", "BBQ"]}, {:thanksgiving=>["Turkey"]},
  #    {:memorial_day=>["BBQ"]}] 
b = a.flat_map(&:to_a)
  #=> [[:christmas, ["Lights", "Wreath"]],
  #    [:new_years, ["Party Hats"]],
  #    [:fourth_of_july, ["Fireworks", "BBQ"]],
  #    [:thanksgiving, ["Turkey"]],
  #    [:memorial_day, ["BBQ"]]] 
c = b.select { |_,a| a.include?("BBQ") }
  #=> [[:fourth_of_july, ["Fireworks", "BBQ"]],
  #    [:memorial_day, ["BBQ"]]] 
c.map(&:first)
  #=> [:fourth_of_july, :memorial_day]