Ruby 确定哈希中是否存在键链

Ruby 确定哈希中是否存在键链,ruby,Ruby,我正在写一些ruby代码,它可以得到一个hash的值,一个hash的值,一个hash的值 amz_price_info.raw["Offers"]["Offer"]["OfferListing"]["Price"]["FormattedPrice"] 我只想在代码的结构器可用时访问此代码。目前,我的代码是: #amz_price_info.raw.class == Hashie::Mash price = if amz_price_info.raw["Offers"]

我正在写一些ruby代码,它可以得到一个hash的值,一个hash的值,一个hash的值

amz_price_info.raw["Offers"]["Offer"]["OfferListing"]["Price"]["FormattedPrice"]
我只想在代码的结构器可用时访问此代码。目前,我的代码是:

    #amz_price_info.raw.class == Hashie::Mash
    price = if amz_price_info.raw["Offers"]
        if amz_price_info.raw["Offers"]["Offer"]
            if amz_price_info.raw["Offers"]["Offer"]["OfferListing"]
                if amz_price_info.raw["Offers"]["Offer"]["OfferListing"]["Price"]
                    if amz_price_info.raw["Offers"]["Offer"]["OfferListing"]["Price"]["FormattedPrice"]
                        amz_price_info.raw["Offers"]["Offer"]["OfferListing"]["Price"]["FormattedPrice"]
                    end
                end
            end
        end
    end

如何重构代码以减少冗长?

此方法允许您在哈希中搜索任意数量的键,如果路径不存在,则返回
nil

def find_value(hash, keys)
  keys.inject(hash.dup) do |prev, key| 
    prev && prev[key] ? prev[key] : nil
  end
end
例如:

info = { "Offers" => { "Offer" => { 
         "OfferListing" => { "Price" => 
       { "FormattedPrice" => 10 }}}}}

keys = %w[Offers Offer OfferListing Price FormattedPrice]
puts find_value(info, keys)                # => 10
puts find_value({"Offers" => {}}, keys)    # => nil

受路易斯的启发,我会这样做:

keys = %w[Offers Offer OfferListing Price FormattedPrice]
price = amz_price_info.raw
keys.each{|k| price = (price||{})[k]}
编辑:如Niklas在评论中所述

# This will return price or nil
keys.inject(amz_price_info.raw) { |price, k| (price || {})[k] }

如果您不想定义额外的方法或引入一些库,这是一种方法

amz_price_info.raw
.fetch("Offers", {})
.fetch("Offer", {})
.fetch("OfferListing", {})
.fetch("Price", {})
.fetch("FormattedPrice", nil)

在Rails 2.3+中,使用
Hash.dig

您的代码可以是:

amz_price_info.dig("Offers", "Offer", "OfferListing", "Price", "FormattedPrice")

这也可以写成
keys.inject(amz|u price_info.raw){| price,k |(price |{})[k]}