2010-03-08 3 views
0

В веб-разработчике я сталкиваюсь с этими проблемами много.Как справиться с рекурсивными родительскими/дочерними проблемами?

К примеру, у нас есть гигантский список URL-адреса, которые находятся в этом формате:

 
/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. как бы вы справились с этим?

+0

вам нужно показать пример из того, что вы считаете грязным –

ответ

0

Не совсем уверен, что тип решения вы после этого, но я хотел бы начать в этом направлении, сначала сделать дерево из вашего списка URL:

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 

, а затем распечатать его рекурсивно, а не с помощью тегов > 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, как это, но идея должна быть такой же.

+0

Спасибо. У меня было несколько схожее решение, но ваше гораздо более элегантное. Однако одним из основных препятствий является то, что каждый ребенок находится в списке родителя. поэтому должен быть

    ...
между тегами h3, h4. У меня возникли проблемы с тем, как закрыть теги списка – Raynard

+0

Я отредактировал код, чтобы обернуть дочерние элементы тегами 'ul'. Проверьте это. –

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. цикл по массиву в представлении и генерировать теги

+0

Короткие, чистые, рабочие. +1 – dimitarvp

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}>" }