通过嵌套的Ruby数组/ YAML解析的最快方法

时间:2011-01-19 22:20:31

标签: ruby yaml

从这个结构中提取third level元素的最简洁方法是什么,只要它不对称:

   yaml = [
    {"Collection"=>[
       {"Jeans"=>[
          {"Trends"=>[
             {"Building on basics"=>"Jeans"},
             {"Unexpected pairings"=>"Jeans"},
             {"Retro chic"=>"Jeans"}    # extract me
          ]},
          {"Styles"=>[
             {"Straight Leg"=>"Straight Leg"},
             {"Bootcut"=>"Bootcut"},
             {"Trouser"=>"Trouser"},
             {"Slim Leg"=>"Slim Leg"}
          ]},
          {"Wash"=>[
             {"Blues"=>"Blues"},
             {"Black/Grey"=>"BlackGrey"},
             {"Whites"=>"Summer Whites"},
             {"Colors"=>"Colors"},
             {"Resin"=>"Resin"}
          ]},
          {"Details"=>[
             {"Embroidered"=>"Embroidered"},
             {"Tuxedo"=>"Tuxedo"},
             {"Jeweled"=>"Jeweled"}
          ]}
       ]},
       {"Bodyshapers"=>[
          {"All"=>[
             {"All"=>"BodyShapers"}
          ]}
       ]}
    ]},
    {"Lift Tuck"=>nil},
    {"Find Us" =>[
       "By City",
       "International Websites",
       "Online Retailers"
    ]},
    {"Your Stories"=>nil},
    {"The Skinny"=>[
       "Trends",
       "Behind the Scenes",
       "VIP Events",
       "In the News",
       "Win a Pair"
    ]}
  ]

1 个答案:

答案 0 :(得分:3)

我不知道最简单的方法,但这样的事情会起作用:

class NthElements
  include Enumerable

  def initialize(yaml, n = 3)
    @yaml = yaml
    @n = n
  end

  def each(&block)
    traverse(@yaml, 0, &block)
  end

  private
  def traverse(value, level, &block)
    if level == @n + 1
      block.call(value)
      return
    end

    case value
    when Array
      value.each { |next_value| traverse(next_value, level + 1, &block) }
    when Hash
      value.values.each { |next_value| traverse(next_value, level, &block) }
    end
  end
end

NthElements.new(yaml).each{|val| p val }