将红宝石哈希转化为html列表 [英] turn a ruby hash into html list
问题描述
a:
a1:
a2:
b:
b1:
b11:
b2:
我得到这样的散列:
{a=> {a1=> nil,a2=> nil},b=> {b1=> {b11=> nil},b2=> nil}}
我想将它变成一个列表:
%ul
%li a
%ul
%li a1
%li a2
%li b
%ul
%li b1
%ul
%li b11
%li b2
我试图以最有效率的方式进行搜索并不重要,哈希值有多深
最后我是这样做的:
关键字=%w(url)
#将多级哈希转换为haml多级树
#特殊关键字
#url:item url
def hash_to_haml(hash,url = nil)
haml_tag(:ul)do
hash.each do | key,value | (key)
url = get_url(key,value)
$ b haml_tag(:li)do
haml_tag(:a (key)
end
hash_to_haml(value)if value.is_a?(Hash)&& amp;& !value.empty?
结束
结束
结束
结束
结束
私人
def get_url(key,hash)
#TODO:从hash $ b $获取完整url如果hash.nil?
/#{key}
else
hash.include?(url)? hash.delete(url):/#{key}
end
end
现在准备解析选项。
要输出为纯HTML,您可以执行递归调用在每个
块中使用相同的函数(或者使用 每个
块)正如我在这里所做的那样):
def hash_to_html key,value
if value.nil?
放置< li>#{key}< / li>
elsif value.is_a?(Hash)
puts< li>#{key}
puts< ul>
value.each(& method(:hash_to_html))
puts< / ul>< / li>
else
失败我不知道如何处理#{value.class}
end
end
puts< UL>中
yourhash.each(& method(:hash_to_html))
puts< / ul>
要输出到您使用的任何模板语言(HAML,我认为),我们需要保留跟踪缩进,所以事情会更复杂一点 - 我们将使用一个函数,它将缩进深度作为参数,并返回另一个函数,以在每个键/值对上调用,以打印该键/值对(递归)和适当的缩进。 (在函数式编程中,以这种方式调用一个函数被称为部分应用函数,并且它们通常比Ruy中的定义要容易一些。)
def hash_to_haml depth
lambda do | key,value |
puts* depth +%li#{key}
如果value.nil?
#什么都不做
#(单个这种情况下,以免引发错误)
elsif value.is_a?(哈希)
puts*(深度+ 1)+%ul
value.each(& hash_to_haml(depth + 2))
else
fail我不知道如何处理#{value.class }
end
end
end
puts%ul
yourhash.each(& hash_to_haml(1))
I'm trying to parse a yaml file like this:
a:
a1:
a2:
b:
b1:
b11:
b2:
i get a hash like this:
{"a"=>{"a1"=>nil, "a2"=>nil}, "b"=>{"b1"=>{"b11"=>nil}, "b2"=>nil}}
and i want to turn it to a list:
%ul
%li a
%ul
%li a1
%li a2
%li b
%ul
%li b1
%ul
%li b11
%li b2
I'm trying to search the most efficent way doesn't matter how deep is the hash
Finally i did in this way:
KeyWords = %w(url)
# Convert a multilevel hash into haml multilevel tree
# Special KeyWords
# url : item url
def hash_to_haml(hash, url = nil)
haml_tag(:ul) do
hash.each do |key, value|
unless KeyWords.include?(key)
url = get_url(key, value)
haml_tag(:li) do
haml_tag(:a, :href => url ) do
haml_concat(key)
end
hash_to_haml(value) if value.is_a?(Hash) && !value.empty?
end
end
end
end
end
private
def get_url(key, hash)
# TODO: get full url from hash
if hash.nil?
"/#{key}"
else
hash.include?("url") ? hash.delete("url") : "/#{key}"
end
end
Now is prepared to parse options too.
To output to plain HTML you can just perform a recursive call of the same function within a each
block (or use the function as the each
block as I have done here):
def hash_to_html key,value
if value.nil?
puts "<li>#{key}</li>"
elsif value.is_a?(Hash)
puts "<li>#{key}"
puts "<ul>"
value.each(&method(:hash_to_html))
puts "</ul></li>"
else
fail "I don't know what to do with a #{value.class}"
end
end
puts "<ul>"
yourhash.each(&method(:hash_to_html))
puts "</ul>"
To output to whatever templating language you're using (HAML, I think), we need to keep track of indentation, so things are a little more complicated -- we're going to use a function that takes the indenting depth as a parameter, and returns another function to be called on each key/value pair that prints that key/value pair (recursively) with appropriate indentation. (In functional programming, calling a function this way is called a "partially applied function", and they're usually a little easier to define than in Ruy.)
def hash_to_haml depth
lambda do |key,value|
puts " "*depth + "%li #{key}"
if value.nil?
# do nothing
# (single this case out, so as not to raise an error here)
elsif value.is_a?(Hash)
puts " "*(depth+1) + "%ul"
value.each(&hash_to_haml(depth+2))
else
fail "I don't know what to do with a #{value.class}"
end
end
end
puts "%ul"
yourhash.each(&hash_to_haml(1))
这篇关于将红宝石哈希转化为html列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!