如何处理像这样的递归父/子问题?

时间:2010-03-08 16:55:09

标签: php ruby recursion

在网络开发中,我经常遇到这些问题。

例如,我们有一个包含这种格式的巨大网址列表:

/businesses  
/businesses/food  
/businesses/food/wendys  
/businesses/food/wendys/chili  
/businesses/food/wendys/fries  
/businesses/food/wendys/chicken-nuggets  
/businesses/pharmacy/cvs  
/businesses/pharmacy/cvs/toothpaste  
/businesses/pharmacy/cvs/toothpaste/brand  
...

然后我们需要输出每一个,其中父类别在h1标签中,子节点在h2标签中,子节点在h3标签中。

我可以处理这个但我觉得我的代码很乱。我确定我可以使用一种设计模式吗? Langs通常是ruby / php。你会怎么处理这个?

4 个答案:

答案 0 :(得分:1)

这个有点压缩,但我希望它有意义。当然,您可以对其进行基准测试以对其进行调整以获得最佳结果。

s.each { |row|
  puts row[1..-1].split('/')[0..2].each_with_index \
  {|v,i| 
    tag = "h#{i+1}";
    print "<#{tag}>#{v}</#{tag}> "
  }
}

更详细

s.each do |row|                             # 'each' will split each row
  row = row[1..-1]                          # string of the row without '/'
  words = row.split('/')                    # split into words
  words = words[0..2]                       # we just need first 3 tags
  words.each_with_index do |word, index|    # get index and value of each element in word array
    tag = "h#{index+1}"                       # use index to dynamically generate tag
    print "<#{tag}>#{word}</#{tag}> "       # use the tag and word to generate output
  end
end

  1. 将方法放在适当位置的库中
  2. 收集数组中的值
  3. 循环遍历数组中的数组查看和生成标签

答案 1 :(得分:0)

不完全确定你所使用的是什么样的解决方案但是我会从这个方向开始,首先从你的网址列表中创建一个树:

s = '/businesses  
/businesses/food  
/businesses/food/wendys  
/businesses/food/wendys/chili  
/businesses/food/wendys/fries  
/businesses/food/wendys/chicken-nuggets  
/businesses/pharmacy/cvs  
/businesses/pharmacy/cvs/toothpaste  
/businesses/pharmacy/cvs/toothpaste/brand'
h = {}
s.split("\n").map(&:strip).each do |row|
  lh = h
  row[1..-1].split('/').each do |item|
    lh[item] ||= {}
    lh = lh[item]
  end
end

然后递归打印,不使用标签&gt; H3:

def rprint h, level=1
  h.each do |k,v|
    puts "<li><h#{level}>#{k}</h#{level}>"
    unless v.empty?
      puts "<ul>"
      rprint(v, level == 3 ? 3 : level + 1)
      puts "</ul>"
    end
    puts "</li>"
  end
end

rprint h

当然,这个打印逻辑会使用体面的模板语言而不是像这样编写HTML来查看视图,但这个想法应该是相同的。

答案 2 :(得分:0)

答案 3 :(得分:0)

这显然需要更多的爱,但也许它会让你开始:

>> path = "/businesses/pharmacy/cvs/toothpaste/brand" 
>> path.split('/',4)[1..-1].each_with_index { |el,i| puts "<h#{i+1}>#{el}</h#{i+1}>" }
<h1>businesses</h1>
<h2>pharmacy</h2>
<h3>cvs/toothpaste/brand</h3>

编辑:这是我能想到的另一种方式:

>> [*0..2].zip(path.split('/',4).drop(1)).each { |i,el| puts "<h#{i}>#{el}</h#{i}>" }