Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Нумерация дерева


Автор: Vardoulacha 9.3.2012, 07:32
Итак деревья, вот такой исходный массив получается из базы, с сортировкой по полю position

Код

    $category[0][] = array('id' => 1, 'position' => 1, 'title' => 'первая');
    $category[1][] = array('id' => 3, 'position' => 1, 'title' => 'первая - первая');
    $category[3][] = array('id' => 6, 'position' => 1, 'title' => 'первая - первая - первая');
    $category[9][] = array('id' => 7, 'position' => 1, 'title' => 'первая - первая - вторая - первая');
    $category[0][] = array('id' => 2, 'position' => 2, 'title' => 'вторая');
    $category[1][] = array('id' => 4, 'position' => 2, 'title' => 'первая - вторая');
    $category[9][] = array('id' => 8, 'position' => 2, 'title' => 'первая - первая - вторая - вторая');
    $category[3][] = array('id' => 9, 'position' => 2, 'title' => 'первая - первая - вторая');
    $category[1][] = array('id' => 5, 'position' => 3, 'title' => 'первая - третья');


это поле parent
Код

$category[0][]


остальные понятны по названию

вот код который за раз строит упорядоченное дерево и выводит его

Код

    function build_tree($category, $parent = 0, $level = 0)
    {
        if(is_array($category) AND count($category[$parent]) > 0)
        {
            foreach($category[$parent] as $categ)
            {
                $padd = $level * 20;
                echo '<div style="padding-left:'.$padd.'px;">'.$categ['position'].'. '.$categ['title'].'</div>';
                build_tree($category, $categ['id'], $level + 1);
            }
        }
    }

    build_tree($category);


и вот результат работы
Код

1. первая
     1. первая - первая
          1. первая - первая - первая
          2. первая - первая - вторая
               1. первая - первая - вторая - первая
               2. первая - первая - вторая - вторая
     2. первая - вторая
     3. первая - третья
2. вторая


и собственно никак не могу придумать каким макаром сделать вот такую красивую нумерацию

Код

1. первая
     1.1. первая - первая
          1.1.1. первая - первая - первая
          1.1.2. первая - первая - вторая
               1.1.2.1. первая - первая - вторая - первая
               1.1.2.2. первая - первая - вторая - вторая
     1.2. первая - вторая
     1.3. первая - третья
2. вторая


понимаю что нужно вроде как-то в функцию сделать сбор всех родителей в переменную path но вот как это собрать не понимаю, помогите плиз

Автор: ksnk 9.3.2012, 08:44
Цитата(Vardoulacha @  9.3.2012,  07:32 Найти цитируемый пост)
каким макаром сделать вот такую красивую нумерацию

Четвертым параметром в build_tree передавай текущий номер -префикс, который будет добавляться всем чилдам.

Автор: MoLeX 9.3.2012, 09:27
http://forum.vingrad.ru/forum/topic-206748.html

Автор: Vardoulacha 9.3.2012, 09:36
MoLeX, да я в первую очередь прочитал эту тему, но там такой кавардак, и в основном сводится к постройке массива дерева в переменной

Цитата(ksnk @  9.3.2012,  08:44 Найти цитируемый пост)
Четвертым параметром в build_tree передавай текущий номер -префикс, который будет добавляться всем чилдам. 

ну это да, тоже думал про префиксы и передавать их параметром, сейчас ухожу не будет компа под рукой, завтра буду пробовать аттачить префикс

мдааа ))) на запрос в гугле "php красивая нумерация дерева" вылазит эта моя тема ))

вот родил вот такой код

Код

    function build_tree($category, $parent = 0, $level = 1, $path = '')
    {
        if(is_array($category) AND count($category[$parent]) > 0)
        {
            foreach($category[$parent] as $categ)
            {
                $padd = ($level - 1) * 20;
                echo '<div style="padding-left:'.$padd.'px;">'.$path.$categ['position'].'. '.$categ['title'].'</div>';
                build_tree($category, $categ['id'], $level + 1, $path .= $level.'.');
            }
        }
    }


теперь результат выглядит так

Код

1. первая
   1.1. первая - первая
      1.2.1. первая - первая - первая
      1.2.3.2. первая - первая - вторая
         1.2.3.3.1. первая - первая - вторая - первая
         1.2.3.3.4.2. первая - первая - вторая - вторая
   1.2.2. первая - вторая
   1.2.2.3. первая - третья
1.2. вторая


теперь осталось вывернуть мозг наизнанку и родить откат пути

Автор: ksnk 9.3.2012, 15:59
Код

...
build_tree($category, $categ['id'], $level + 1, $path .$level.'.');// БЕЗ ПРИСВАИВАНИЯ!
...

Автор: MoLeX 9.3.2012, 17:09
эх. раньше голову тоже ломал с этими деревьями, http://www.google.ru/#hl=ru&gs_nf=1&cp=6&gs_id=14&xhr=t&q=nested+sets&pf=p&newwindow=1&safe=off&sclient=psy-ab&oq=nested&aq=0&aqi=g4&aql=&gs_sm=&gs_upl=&gs_l=&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&fp=db0bef8c820c64df&biw=1920&bih=890

Автор: Vardoulacha 9.3.2012, 17:23
ksnk, блииин, не может быть что всё так просто )) но радость была короткой

вот при таком коде, результат правильный, но как только добавляю ещё один уровень вложенности, всё ломается
Код

    function build_tree($category, $parent = 0, $level = 0, $path = '')
    {
        if(is_array($category) AND count($category[$parent]) > 0)
        {
            foreach($category[$parent] as $categ)
            {
                $padd = $level * 20;
                echo '<div style="padding-left:'.$padd.'px;">'.$path.$categ['position'].'. '.$categ['title'].'</div>';
                ($level == 0 ? $path_level = 1 : $path_level = $level);
                build_tree($category, $categ['id'], $level + 1, $path.$path_level.'.');
            }
        }
    }


если к начальному массиву добавить это
Код

    $category[7][] = array('id' => 10, 'position' => 1, 'title' => 'первая - первая - вторая - первая - первая');
    $category[7][] = array('id' => 11, 'position' => 2, 'title' => 'первая - первая - вторая - первая - вторая');


результат будет такой
Код

1. первая
   1.1. первая - первая
      1.1.1. первая - первая - первая
      1.1.2. первая - первая - вторая
         1.1.2.1. первая - первая - вторая - первая
            1.1.2.3.1. первая - первая - вторая - первая - первая
            1.1.2.3.2. первая - первая - вторая - первая - вторая
         1.1.2.2. первая - первая - вторая - вторая
   1.2. первая - вторая
   1.3. первая - третья
2. вторая


нутром понимаю что дело тут в параметре position который отдельно вставляется, а должен тоже идти с путем как-то, вот сижу смотрю на код и вижу фигу ((

а и ещё вот вижу что проблема немного глубже, сейчас структура легкая, а если дерево усложнить и добавить веток то проблема нумерации встанет более явно, сейчас она по порядку идет ветвление и поэтому примерно даже работает, на более низких только заметно, а если взять массив такой

Код

    $category[0][] = array('id' => 1, 'position' => 1, 'title' => 'первая');
    $category[1][] = array('id' => 3, 'position' => 1, 'title' => 'первая - первая');
    $category[3][] = array('id' => 6, 'position' => 1, 'title' => 'первая - первая - первая');
    $category[9][] = array('id' => 7, 'position' => 1, 'title' => 'первая - первая - вторая - первая');
    $category[0][] = array('id' => 2, 'position' => 2, 'title' => 'вторая');
    $category[1][] = array('id' => 4, 'position' => 2, 'title' => 'первая - вторая');
    $category[9][] = array('id' => 8, 'position' => 2, 'title' => 'первая - первая - вторая - вторая');
    $category[3][] = array('id' => 9, 'position' => 2, 'title' => 'первая - первая - вторая');
    $category[1][] = array('id' => 5, 'position' => 3, 'title' => 'первая - третья');
    $category[7][] = array('id' => 10, 'position' => 1, 'title' => 'первая - первая - вторая - первая - первая');
    $category[7][] = array('id' => 11, 'position' => 2, 'title' => 'первая - первая - вторая - первая - вторая');
    $category[6][] = array('id' => 12, 'position' => 1, 'title' => 'первая - первая - первая - первая');
    $category[6][] = array('id' => 13, 'position' => 2, 'title' => 'первая - первая - первая - вторая');
    $category[6][] = array('id' => 14, 'position' => 3, 'title' => 'первая - первая - первая - третья');
    $category[10][] = array('id' => 15, 'position' => 1, 'title' => 'первая - первая - вторая - первая - первая - первая');


то результат будет уже вот такой
Код

1. первая
   1.1. первая - первая
      1.1.1. первая - первая - первая
         1.1.2.1. первая - первая - первая - первая
         1.1.2.2. первая - первая - первая - вторая
         1.1.2.3. первая - первая - первая - третья
      1.1.2. первая - первая - вторая
         1.1.2.1. первая - первая - вторая - первая
            1.1.2.3.1. первая - первая - вторая - первая - первая
               1.1.2.3.4.1. первая - первая - вторая - первая - первая - первая
            1.1.2.3.2. первая - первая - вторая - первая - вторая
         1.1.2.2. первая - первая - вторая - вторая
   1.2. первая - вторая
   1.3. первая - третья
2. вторая


Добавлено через 7 минут и 5 секунд
MoLeX, что-то мне не нравится nested sets из-за лишних данных в базе, в данном коде только id да parent_id

единственная проблема с красивую нумерацию построить

Автор: ksnk 9.3.2012, 17:52
Код

function build_tree($category, $parent = 0, $level = 0, $path = '')
    {
        if(is_array($category) AND count($category[$parent]) > 0)
        {
            $number=1;
            foreach($category[$parent] as $categ)
            {
                $padd = $level * 20;
                echo '<div style="padding-left:'.$padd.'px;">'.$path.$categ['position'].'. '.$categ['title'].'</div>';
                build_tree($category, $categ['id'], $level + 1, $path.($number++).'.');
            }
        }
    }

Автор: MoLeX 9.3.2012, 18:37
Цитата(Vardoulacha @  9.3.2012,  17:23 Найти цитируемый пост)
MoLeX, что-то мне не нравится nested sets из-за лишних данных в базе, в данном коде только id да parent_id

единственная проблема с красивую нумерацию построить


левый и правый ключ еще добавляется. зато очень удобно выводить и все просто. надо только разобраться

Автор: Vardoulacha 10.3.2012, 04:51
ksnk, неужели всё так просто, хотя я бы никогда не догадался, спасибо огромное, вот и появился в интернете полный пример по сбору дерева из базы и по его красивому выводу

MoLeX, ну вот из-за левого и правого ключа как и лишние данные, объем данных в жертву удобству

Автор: gta4kv 10.3.2012, 08:22
Объем данных? Вы о двух столбцах с INT'выми значениями? Ну-ну..

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)