Einen Hirarchischen-Baum aus einer Liste erstellen

Mmmh...das verstehe ich jetzt nicht, was du meinst.

Ich sehe bei Mathias' Array:
Code:
$inputArray = array(
    array( 'ID' => 1, 'parentID' => 0, 'title' => 'Element1' ),
    array( 'ID' => 2, 'parentID' => 1, 'title' => 'Element2' ),
    array( 'ID' => 3, 'parentID' => 2, 'title' => 'Element3' ),
    array( 'ID' => 4, 'parentID' => 2, 'title' => 'Element4' ),
    array( 'ID' => 5, 'parentID' => 3, 'title' => 'Element5' ),
    array( 'ID' => 6, 'parentID' => 3, 'title' => 'Element6' ),
);
...und bei meinem Array:
Code:
$items = array(
    array( 'ID' => 1,   'pID' => 0, 'title' => 'Drinks' ),
    array( 'ID' => 2,   'pID' => 1, 'title' => 'Bier' ),
    array( 'ID' => 3,   'pID' => 1, 'title' => 'Wein' ),
    array( 'ID' => 4,   'pID' => 1, 'title' => 'Schnaps' ),
    array( 'ID' => 6,   'pID' => 2, 'title' => 'Radeberger' ,'href'=>'http://www.radeberger.de'),
    array( 'ID' => 7,   'pID' => 2, 'title' => 'Edelstoff' ),
    array( 'ID' => 8,   'pID' => 3, 'title' => 'Rotwein' ),
    array( 'ID' => 9,   'pID' => 3, 'title' => 'Weisswein' ),
    array( 'ID' => 10,  'pID' => 4, 'title' => 'Wodka' ),
    array( 'ID' => 11,  'pID' => 4, 'title' => 'Whisky' ),
    array( 'ID' => 14,  'pID' => 8, 'title' => 'Bordeaux' ),
    array( 'ID' => 16,  'pID' => 9, 'title' => 'Riessling' )
);
...keine entscheidenden Unterschiede. Falls du die Namen der ArraySchlüssel meinst...benenne sie einfach um.
 
das stimmt, das input Array ist identisch aufgebaut. Aber das output Array, dass dann als Liste ausgegeben werden soll, hat bei dir doch ein Kennzeichen, falls eine Unterkategorie existiert. (array['child']).
Die fehlt mir.

Ich hätte das ganze gern halbwegs einfach (= dass ich es noch halbwegs kapiere ;)) gehalten, also ohne Klassen gearbeitet.

Kurzum: Ich würde sehr gerne aus diesem Array (nach Matthias' Funktion ermittelt):
Code:
Array
(
    [1] => Array
        (
            [bezeichnung] => FH Weihenstephan
            [3] => Array
                (
                    [bezeichnung] => Fachbereich LE
                    [5] => Array
                        (
                            [bezeichnung] => Landwirtschaft
                        )

                    [6] => Array
                        (
                            [bezeichnung] => Agrarmarketing und -management
                            [7] => Array
                                (
                                    [bezeichnung] => Skripte und Ähnliches
                                )

                            [8] => Array
                                (
                                    [bezeichnung] => Prüfungen
                                )

                        )

                )

            [4] => Array
                (
                    [bezeichnung] => Fachbereich LA
                )

        )

    [2] => Array
        (
            [bezeichnung] => TU München
            [9] => Array
                (
                    [bezeichnung] => Ernährungswissenschaften
                )

            [10] => Array
                (
                    [bezeichnung] => Agrarwissenschaften
                    [11] => Array
                        (
                            [bezeichnung] => Prüfungen
                        )

                    [12] => Array
                        (
                            [bezeichnung] => Skripte u.ä.
                        )

                )

        )

)
ein Listenmenü erstellen. :)

Wenn ich hier im Forum und auch bei Google die Suchergebnisse zu diesem Thema sehe, glaube (und hoffe ;)) ich, dass ich nicht der einzige bin, der zu doof ist, das zu verstehen und sich über eine möglichst einfache Lösung freuen würde :)
 
Zuletzt bearbeitet:
Hallo,
so
PHP:
<?php
    function generateList($array, &$output=''){
        $output .= '<ul>';
        foreach ($array as $arr){
            if (is_array($arr)){
                generateList($arr, $output);
            } else {
                $output .= '<li>'.$arr.'</li>';
            }
        }
        $output .= '</ul>';
        return str_replace('</ul><ul>', '', substr($output, 4, -5));
        // Die folgende Zeile generiert eine ul-List, die für dieses Tutorial (http://www.tutorials.de/forum/javascript-tutorials/164340-javascript-treemenu.html) verwendet werden könnte
        #return str_replace('</ul></ul>', '</ul></li></ul>', str_replace('</ul><li>', '</ul></li><li>', str_replace('</li><ul><li>', '<ul><li>', str_replace('</ul><ul>', '', substr($output, 4, -5)))));
    }

    $inputArray = array(
        array( 'ID' => 1, 'parentID' => 0, 'title' => 'Element1' ),
        array( 'ID' => 2, 'parentID' => 1, 'title' => 'Element2' ),
        array( 'ID' => 3, 'parentID' => 2, 'title' => 'Element3' ),
        array( 'ID' => 4, 'parentID' => 2, 'title' => 'Element4' ),
        array( 'ID' => 5, 'parentID' => 3, 'title' => 'Element5' ),
        array( 'ID' => 6, 'parentID' => 3, 'title' => 'Element6' ),
        array( 'ID' => 7, 'parentID' => 0, 'title' => 'Element7' ),
        array( 'ID' => 8, 'parentID' => 7, 'title' => 'Element8' ),
        array( 'ID' => 9, 'parentID' => 7, 'title' => 'Element9' ),
        array( 'ID' => 10, 'parentID' => 0, 'title' => 'Element10' ),
        array( 'ID' => 11, 'parentID' => 0, 'title' => 'Element11' ),
    );
    
    $outputArray = array();
    $nodeRefs = array(0 => &$outputArray);
    
    foreach ($inputArray as $element) {
        $parent = &$nodeRefs[$element['parentID']];
        $parent[$element['ID']] = array('title' => $element['title']);
        $nodeRefs[$element['ID']] = &$parent[$element['ID']];
    }
    
    echo generateList($outputArray);
?>
//Edit: Hab die Funktion jetzt (02.08.2006) ein wenig geändert, sodass sie meiner Meinung nach besser ist, da auf [phpf]global[/phpf] verzichtet werden kann.
sollte es funktionieren.

mfg
forsterm
 
Zuletzt bearbeitet:
super, 1000 Dank!

Die Ausgabe is ja recht einfach, wenn man weiß, wie sie geht :)

Ich hoffe, dass ich es jetzt endlich hin bekomme, aber das ganze noch in eine select-Box mit ID als Wert zu packen, sollte zu schaffen sein.

Probiere an dem Menü schon ein "paar" Tage rum...

Deshalb nochmal vielen Dank für Eure super Hilfe!
 
Hier noch als Ergänzung das ganze wie oben nur als SELECT Feld ausgegeben und das Array über ein SQL-Query erzeugt:

PHP:
<?php

/** DB auslesen und inputArray erzeugen **/

$connect = mysql_connect('localhost', 'usr', 'pwd');
mysql_select_db('db1');

$j=0;
$rescat1 = mysql_query("SELECT ID, parentID, title FROM categories ORDER BY parent");
while ($row = mysql_fetch_assoc($rescat1)) {
  foreach($row as $key => $value) {
    $inputArray[$j] [$key] = $value;
  }
  $j++;
}

/*
// oder zum Testen ohne DB
    $inputArray = array(
        array( 'ID' => 1, 'parentID' => 0, 'title' => 'Element1' ),
        array( 'ID' => 2, 'parentID' => 1, 'title' => 'Element2' ),
        array( 'ID' => 3, 'parentID' => 2, 'title' => 'Element3' ),
        array( 'ID' => 4, 'parentID' => 2, 'title' => 'Element4' ),
        array( 'ID' => 5, 'parentID' => 3, 'title' => 'Element5' ),
        array( 'ID' => 6, 'parentID' => 3, 'title' => 'Element6' ),
        array( 'ID' => 7, 'parentID' => 0, 'title' => 'Element7' ),
        array( 'ID' => 8, 'parentID' => 1, 'title' => 'Element8' ),
        array( 'ID' => 9, 'parentID' => 1, 'title' => 'Element9' ),
    );
*/


    echo "Array:<pre>";
    print_r($inputArray);
    echo "</pre>";


/** Hierarchie ermitteln **/

    $outputArray = array();
    $nodeRefs = array(0 => &$outputArray);
    foreach ($inputArray as $element) {
        $parent = &$nodeRefs[$element['parentID']];
        $parent[$element['ID']] = array('title' => $element['title']);
        $nodeRefs[$element['ID']] = &$parent[$element['ID']];
    }

    echo "Array:<pre>";
    print_r($outputArray);
    echo "</pre>";

/** outputArray als SELECT-Feld ausgeben **/

    $output = '';
    $i='';
    $id = 0;
    function generateList($array, $i, $id){
        global $output;
        foreach ($array as $key => $value){
            if (is_array($value)){
              $id = $key;
              generateList($value, $i, $id);
            } else {
                $output .= "<option value='".$id."'>".$i.$value."</option>\n";
                $i .='&nbsp; &nbsp; ';
            }
        }

        $i = '';
        return $output;
    }

    echo "<select name='cat_id' size='1'>\n";
    echo generateList($outputArray, $i, $id);
    echo "</select>\n";

?>
 
Zuletzt bearbeitet:
Hallo,

das hier:
ballistic hat gesagt.:
PHP:
$j=0;
$rescat1 = mysql_query("SELECT ID, parentID, title FROM categories ORDER BY parent");
while ($row = mysql_fetch_assoc($rescat1)) {
  foreach($row as $key => $value) {
    $inputArray[$j] [$key] = $value;
  }
  $j++;
}
kann allerdings auch verkürzen werden zu:
PHP:
$rescat1 = mysql_query("SELECT ID, parentID, title FROM categories ORDER BY parent");
$inputArray = array();
while ($row = mysql_fetch_assoc($rescat1)) {
	$inputArray[] = $row;
}

Grüße,
Matthias
 
Hallo habe noch ein kleines Problem sonst funktioniert es super ;-)

Ich möchte gern für jeden Eintrag noch eine ID mit ausgeben habe aber keine Ahnung wie ich das mit dem Arrays machen soll. D.h ich möcht efür jeden Punkt noch eine ID (für einen Link) ausgeben. Gibt es da eine Möglichkeit?
PHP:
    $inputArray = array(
        array( 'ID' => 1, 'parentID' => 0, 'title' => 'Element1', 'kID' => '4711' ),
    );
    
    $outputArray = array();
    $nodeRefs = array(0 => &$outputArray);
    
    foreach ($inputArray as $element) {
        $parent = &$nodeRefs[$element['parentID']];
        $parent[$element['ID']] = array('title' => $element['title'], 'kID' => $element['kID']);
        $nodeRefs[$element['ID']] = &$parent[$element['ID']];
    }
 
Id

Hi,
schau dir doch mal meinen vorigen Post an, die Ausgabe als select-Feld. Dort geb ich den Array-Schlüssel, der ja der ID entspricht, mit aus. Hatte nämlich genau das gleiche Problem wie du.
 
So habe es mir noch mal durch den Kopf gehen lassen. Genau das war es was ich gesucht habe vielen Dank!!

ballistic hat gesagt.:
Hi,
schau dir doch mal meinen vorigen Post an, die Ausgabe als select-Feld. Dort geb ich den Array-Schlüssel, der ja der ID entspricht, mit aus. Hatte nämlich genau das gleiche Problem wie du.
 
Zuletzt bearbeitet:
Dieses Problem ließe sich sehr schön mittels Referenzen lösen:
PHP:
<?php

$inputArray = array(
	array( 'ID' => 1, 'parentID' => 0, 'title' => 'Element1' ),
	array( 'ID' => 2, 'parentID' => 1, 'title' => 'Element2' ),
	array( 'ID' => 3, 'parentID' => 2, 'title' => 'Element3' ),
	array( 'ID' => 4, 'parentID' => 2, 'title' => 'Element4' ),
	array( 'ID' => 5, 'parentID' => 3, 'title' => 'Element5' ),
	array( 'ID' => 6, 'parentID' => 3, 'title' => 'Element6' ),
);

$outputArray = array();
$nodeRefs = array(0 => &$outputArray);

foreach ($inputArray as $element) {
	$parent = &$nodeRefs[$element['parentID']];
	$parent[$element['ID']] = array('title' => $element['title']);
	$nodeRefs[$element['ID']] = &$parent[$element['ID']];
}

print_r($outputArray);

?>

Eine Alternative wäre die Verwendung der Methode „Modified Preorder Tree Traversal“.

Das ganze funktioniert nur, wenn der erste Eintrag auch die niedrigste ID hat. Setzt man die ID des ersten Eintrags auf z.B. 999 liefert es nur noch diesen Eintrag.
 
Zurück