从 Ruby 中的嵌套哈希返回值

returning value from nested hashes in Ruby

我想 return 所有以 "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

我的代码 return 出现此错误:

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

谢谢!

问题:

您遇到此错误:

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

因为您在符号上调用了 .eachseason.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]

@KMRakibulIslam 已经回答了你的问题,但我认为还有另一种方法很 Ruby-like:

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]