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


Автор: Jozefina 3.3.2009, 18:36
подскажите, пожалуйста!
есть массив из БД
    [1]1;8;25;36
    [2]1;8;24;37
    [3]2;6
    [4]2;5;29
    [5]2;6;38
    [6]3;17
который необходимо превратить в дерево такого типа
    *1
    __*8
    ____*24
    ______*37
    ____*25
    ______*36
    *2
    __*5
    ____*29
    __*6
    ______*38
    *3
    __*17
как тут лучше поступить???? при этом , знаю точно, что родителя будет только три(1,2,3), а глубина не больше 4 вложения...
 smile 

Автор: IZ@TOP 3.3.2009, 19:55
Цитата(Jozefina @  3.3.2009,  19:36 Найти цитируемый пост)
есть массив из БД

[1]1;8;25;36
[2]1;8;24;37
[3]2;6
[4]2;5;29
[5]2;6;38
[6]3;17


О_О *фшоке* Для понимания, хотелось бы условия задачи услышать, поскольку я не представляю как вообще приведенные данные интерпретировать.

Автор: Jozefina 3.3.2009, 20:31
Цитата(IZ@TOP @ 3.3.2009,  19:55)
Цитата(Jozefina @  3.3.2009,  19:36 Найти цитируемый пост)
есть массив из БД

[1]1;8;25;36
[2]1;8;24;37
[3]2;6
[4]2;5;29
[5]2;6;38
[6]3;17


О_О *фшоке* Для понимания, хотелось бы условия задачи услышать, поскольку я не представляю как вообще приведенные данные интерпретировать.

полученный элемент массива имеет до 4 уровня вложенности, который представлен в одной строке
к примеру,  "1;8;25;36"
родитель 1 имеет дочерний элемент 8, у которого, в свою очередь, есть свой дочерний элемент 25, и т.д.
как видно, уровни отделены точкой с запятой...
эта запись в БД-логе может повторяться"1;8;25;36",
поэтому необходимо вытянуть массив этих строк из БД и представить(записать) в виде нормального дерева (массива)...
 smile 

Автор: Цербер 4.3.2009, 10:32
Jozefina ну так выводи всё цикле и в итоге у тебя получится 4 цикла:
в первом вытаскиваешь из базы все данные по 1 значению элемента массива
во втором проверяешь дочерние элементы и т.д. примерно будет выглядеть так:
Код

$query = mysql_query("anyone select");
while($row = mysql_fetch_array($query)){
     echo $row['title'];
     $query_second = mysql_query("anyone select where parent_id='".$row['id']."' ");
     while($row_second = mysql_fetch_array($query_second)){
         echo $row_second['title'];  
            продолжай циклы пока разветвления не закончатся  
     }
}
 
это самый лёгкий способ=) так же можешь использовать один сложный запрос с помощью JOIN-а и псевдонимов для полей! 

Автор: Jozefina 4.3.2009, 12:42
Цитата(Цербер @ 4.3.2009,  10:32)
Jozefina ну так выводи всё цикле и в итоге у тебя получится 4 цикла:
в первом вытаскиваешь из базы все данные по 1 значению элемента массива
во втором проверяешь дочерние элементы и т.д. примерно будет выглядеть так:
Код

$query = mysql_query("anyone select");
while($row = mysql_fetch_array($query)){
     echo $row['title'];
     $query_second = mysql_query("anyone select where parent_id='".$row['id']."' ");
     while($row_second = mysql_fetch_array($query_second)){
         echo $row_second['title'];  
            продолжай циклы пока разветвления не закончатся  
     }
}
 
это самый лёгкий способ=) так же можешь использовать один сложный запрос с помощью JOIN-а и псевдонимов для полей!

что-то я не совсем поняла...
у меня в БД в поле "location" одна запись такая "1;8;25;36", вторая такая "1;8;24;37"...которые я и вытаскиваю в массив...
как я могу вытащить из базы все данные по 1 значению элемента массива???т.е. из записи "1;8;25;36" я получу "1", а потом "8", потом "25" и т.д.
"SELECT id, location as title from database"-первый запрос, а второй: "SELECT id, location as title from database where parent_id='".$row['id']"
 smile 
я думала, необходимо использовать рекурсивную функцию ,это во-первых, а во-вторых использовать то, что я заранее знаю первых родителей("1","2","3")

Автор: skyboy 4.3.2009, 13:33
сходу код не напишу, но чтоб совсем не бросать без поддержки, предлагаю посмотреть тему "http://forum.vingrad.ru/forum/topic-206748/index.html" - там есть вариант построение многомерного массива по матрице смежности(рекурсивно и через ссылки). У тебя не совсем матрица смежности, но, я уверен, вполне можно  тот код под твои условия адаптировать.

Автор: dmitryttt 4.3.2009, 13:38
Может (если еще не поздно) перейти к другой схеме таблиц в БД ... Хранить в одной ячейке данные типа 1;2;3;4 .. крайне нежелательно...и думаю где-то вы можете упереться в большие проблемы

схема  (id | id_parent | data) либо (id | data + id | id_parent) гораздно практичнее

Автор: Jozefina 4.3.2009, 13:55
Цитата(dmitryttt @ 4.3.2009,  13:38)
Может (если еще не поздно) перейти к другой схеме таблиц в БД ... Хранить в одной ячейке данные типа 1;2;3;4 .. крайне нежелательно...и думаю где-то вы можете упереться в большие проблемы

схема  (id | id_parent | data) либо (id | data + id | id_parent) гораздно практичнее

с радостью бы, но надо исходить из того, что есть...

Автор: IZ@TOP 4.3.2009, 14:35
Ну, если предположить, что я вас действительно правильно понял - скрипт будет выглядеть примерно таким образом.

Код

<?php

function aWnFormat($ns, &$array) {
    $n = array_shift($ns);
    if (!array_key_exists($n, $array)) {
        $array[$n] = array();
    }

    ksort($array);
    if (sizeof($ns)) {
        aWnFormat($ns, $array[$n]);
    }
}

function aWnFormatPrint($ns, $l = 0) {
    foreach($ns as $n => $sn) {
        print str_pad("*" . $n, $l+strlen($n), "_", STR_PAD_LEFT) . "\n";
        if(is_array($sn)) {
            aWnFormatPrint($sn, $l+2);
        }
    }
}

// rows from db
$row[]="1;8;25;36";
$row[]="1;8;24;37";
$row[]="2;6";
$row[]="2;5;29";
$row[]="2;6;38";
$row[]="3;17";

$array = array();

foreach ($row as $s) {
    $ns = explode(';', $s);
    aWnFormat($ns, $array);
}

ksort($array);
aWnFormatPrint($array);

?>



Просто было любопытно мозки размять. По идее, эти две функи поддерживают бесконечно возможное число родителей и вложений (насколько мощностей хватит smile).

P.S. aWnFormat - array woman format)))

Автор: Jozefina 4.3.2009, 17:31
IZ@TOP
спасибочки!

Автор: IZ@TOP 4.3.2009, 17:42
 smile 
Но все равно, советую учиться думать собственной головой.

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