2012-03-12 40 views
2

我正在写去一个哈希散列的散列值Ruby代码....确定是否钥匙链是existant在哈希

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 

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

回答

5

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

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

这个方法可以让你搜索下一个哈希任何数字键,返回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 
2

通过louism我会启发这样做:

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] } 
+4

这也可以写成'keys.inject(amz_price_info.raw){ |价格,k | (价格|| {})[K]}' – 2012-03-13 00:00:44