Ruby中的双递归

时间:2014-07-29 21:51:58

标签: ruby recursion

我正在尝试将符号的嵌套数组解析为HTML,我的输入是:

[[:html,
  [:head, [:title, "Hello World"]],
  [:body, [:h1, "Hello World"], [:p, "This is your parser"]]]]

我的预期输出是:

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h1> Hello World </h1>
    <p> This is your parser</p>
  </body>
</html>

我的方法是:

def to_html(data)
 if( data.is_a?(Array))

   open_map = data.map do |item|
    if( item.is_a?(Array))
      to_html(item)
    else
      if( item.is_a?(Symbol))
        "<"+ item.to_s + ">"
      else
        item.to_s
      end
    end
  end

  close_map = data.map do |item|
    if( item.is_a?(Array))
      to_html(item)
    else
      if( item.is_a?(Symbol))
        "</"+ item.to_s + ">"
      end
    end
  end
      open_map.join(' ')   + close_map.join(' ')
  else
    data.to_s
  end
end

这基本上有效,只是因为我认为对to_html的两次递归调用导致双输出

即:

<html> 
 <head>
   <title> Hello World
   </title>
 </head> 
   <title> Hello World
  </title>
<body>
. . . .

等等

我认为我需要嵌套递归或者过滤结果

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

如果假设每个数组的第一个元素是标记名称,那么它可以简化为:

def to_html(data)
  if (data.is_a?(Array))
    tag = data[0]
    children = data[1..-1]
    return "<#{tag}>" + children.map {|x| to_html(x)}.join(' ') + "</#{tag}>"
  else
    return data
  end
end

print to_html([:html,
               [:head, [:title, "Hello World"]],
               [:body, [:h1, "Hello World"], [:p, "This is your parser"]]])

打印

<html><head><title>Hello World</title></head> <body><h1>Hello World</h1> <p>This is your parser</p></body></html>