Quickest way to parse through nested Ruby arrays / YAML
What's the cleanest way to extract third level
elements from this structure provided that it's not symmetrical:
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"
]}
]
I don't know about the easiest way, but something like this would work:
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 }
精彩评论