OVH Cloud OVH Cloud

Affichage d'une liste arborescente

10 réponses
Avatar
Batman
Bonjour,
Je n'arrive pas à me faire une fonction (recursive ?) qui m'afficherait une
liste de façon arborescente.
Je cherche à faire le code le plus compacte pour réutilisation facile dans
d'autres contexte, et je n'ais pas de limite (fixé) dans la profondeur de
l'arborescence.

D'avance Merci

Soit le tableau ci-dessous :

Id Parent Lib
1 0 Auto/motos/bateaux
2 1 Moto
3 1 voiture
4 1 bateau
5 2 <500 cm3
6 2 >500 cm3
7 0 Immobilier
8 7 location
9 7 achat
10 7 vente

au sens php du terme $Categorie[] = array ("Id"=> 1, "Parent" =>0,"Lib" =>
"Auto/motos/bateaux") ....

Voila ce que je voudrais voir (les '.' représente le décalage par rapport au
noeud père) :
Auto/motos/bateaux(1)
.Moto(2)
..<500 cm3(5)
..>500 cm3(6)
.voiture(3)
.bateau(4)
Immobilier(7)
.location(8)
.achat(9)
.vente(10)

J'ai galéré un peu, mais mon code bug à partir du 2iem niveau : j'ai
".<500 cm3(5)" au lieu de "..<500 cm3(5)"

Je livre ce que j'ai déjà fait, si ça peut aider à me dépanner :
function Tree ($Array,$IdParent=0,$retrait=0) {
$Action="rien";
foreach ($Array as $item) {
$SonPere=$item['Parent'];
$SonId=$item['ID'];
$SonLib=$item['Lib'];
if ( ($SonPere == 0 ) && ( $IdParent == 0 ) ){ $Action="NoeudDeBase"; }
if ( ($SonPere == $IdParent ) && ( $IdParent > 0 ) )
{ $Action="IlEstSonFils"; }
//if ( ($SonPere == $IdParent ) && ( $IdParent > 0 ) &&
( $Action=="NODE" ) ) { $Action="IlEstSonFilsNoeud"; }
$Texte=str_repeat(".", $retrait)."$SonLib($SonId)";
switch ($Action) {
case "IlEstSonFils":
$NewRetrait++;
echo Affiche($Texte,$retrait)."$SonPere=$IdParent? ";
Tree($Array,$SonId,$NewRetrait);
break;
case "NoeudDeBase":
$NewRetrait=1;
echo Affiche($Texte,$retrait)."$SonPere=$IdParent? ";
Tree($Array,$SonId,$NewRetrait);
break;
default:
//
break;
}
$Action="rien";
}


Note: les liens ci-dessous n'ont pas répondu à ma question (par manque de
connaissance de ma part, ou ne correspondant pas à ma demande)
-
http://groups.google.fr/groups?hl=fr&lr=&frame=right&th=8ffe56cd779324c7&seekm=abtnpm%242m5p%241%40norfair.nerim.net#link1
http://groups.google.fr/groups?hl=fr&lr=&frame=right&th=aa7908c46d3519c1&seekm=buqjr6%247vu%241%40news-reader3.wanadoo.fr#link1

--
Les fautes d'orthographes sont ma signature :-)
pour me répondre en BAL (mode antispam)
http://batman.dyndns.org/V2/Mail/?src=news.free

10 réponses

Avatar
laurent vilday
Batman <41e7fd1b$0$5735$

Je n'arrive pas à me faire une fonction (recursive ?) qui
m'afficherait une liste de façon arborescente.
Je cherche à faire le code le plus compacte pour réutilisation
facile dans d'autres contexte, et je n'ais pas de limite (fixé) dans
la profondeur de l'arborescence.


j'ai une petite classe php qui pourra peut etre t'aider a faire
qqchose qui correspond a ton besoin.
https://sourceforge.net/projects/treedp/
la demo http://mokhet.com/tree/
les bugs c'est la : (ca m'obligera a récupérer ma
clé ssh sur ma partition windows :)

les sources sont accessibles sur sourceforge, que par cvs pour
l'instant.
$ cvs -d:pserver::/cvsroot/treedp login
$ cvs -z3 -d:pserver::/cvsroot/treedp co
treedp

--
laurent

Avatar
Batman

https://sourceforge.net/projects/treedp/
la demo http://mokhet.com/tree/
les bugs c'est la : (ca m'obligera a récupérer ma
clé ssh sur ma partition windows :)



Merci Je vais regarder cela ! cela à l'air d'être une bonne base de travail.
Je pense que les modifications que je ferais seront:
- Gestion autre que des fichiers ;-)
- retirer la gestion 'javascript'

--
Les fautes d'orthographes sont ma signature :-)
pour me répondre en BAL (mode antispam)
http://batman.dyndns.org/V2/Mail/?src=news.free

Avatar
Marc

Je cherche à faire le code le plus compacte pour réutilisation facile dans
d'autres contexte, et je n'ais pas de limite (fixé) dans la profondeur de
l'arborescence.


le plus compact est sans doute en opposition avec réutilisabilité.
Pour etre réutilisable, le code doit présenter cette structure, ce
qui n'est pas le cas du code que tu as fourni :

* extraction des données (fichier, base ..)
* préparation des données en structure facilement exploitable (ce
que fait cette classe ci-dessous)
* affichage si nécessaire.


voici les classes php que j'ai réalisé pour toi (et pour le fun) :
on notera en meme temps, l'arbre construit avec des références.
Si les objets sont copiés, rien ne fonctionne, attention a bien
garder le mécanisme des réferences.

de meme, la boucle foreach fait des recopies d'objets. C'est pour
cela que je me sert de l'index pour acceder au tableau des fils
dans search_node() qui doit obligatoirement retourner une reference
dans l'arbre et pas une recopie d'un objet extrait de cet arbre.



<?php

error_reporting(E_ALL);

class Node{
var $id;
var $val;
var $childs;

function Node($id, $val){
$this->id = $id;
$this->val = &$val;
$this->childs = array();
}

function id(){
return $this->id;
}

function &value(){
return $this->value;
}

function add_node($node){
$this->childs[] = &$node;
}

function &search_node($id){
if($this->id() == $id)
return $this;
else{
foreach($this->childs as $key => $node){
$n = &$this->childs[$key]->search_node($id);
if($n !== FALSE)
return $n;
}
}
return FALSE;
}

function to_text(){
echo "Node : {$this->id} : {$this->val}n";
foreach($this->childs as $node){
$node->to_text();
}
}

function dump($level = 0){
$space = str_repeat(' ', $level);
echo "{$space}Node: {$this->val}n";
foreach($this->childs as $node){
$node->dump($level+1);
}
}
}

class Tree{
var $list;
var $tree;

function Tree(&$list){
$this->list = &$list;
$this->tree = new Node(0, 'root');
$this->build();
}

function build(){
foreach ($this->list as $entry){
$id = $entry['id'];
$parent= $entry['parent'];
$val = $entry['lib'];

if($parent == 0){
# echo "racine ($id) : {$entry['lib']}n";
$this->tree->add_node(new Node($id, $val));
}
else{
# echo "($id) feuille ($parent) : {$entry['lib']}n";
$node = & $this->id2node($parent);
$node->add_node(new Node($id, $val));
}
}
}

function &id2node($id){
return $this->tree->search_node($id);
}

function node2id(&$node){
}
function dump(){
$this->tree->dump();
}
}


$list = array(
array('id' => 1, 'parent' => 0, 'lib' => 'Auto/motos/bateaux'),
array('id' => 2, 'parent' => 1, 'lib' => 'Moto'),
array('id' => 3, 'parent' => 1, 'lib' => 'Voiture'),
array('id' => 4, 'parent' => 1, 'lib' => 'Bateau'),
array('id' => 5, 'parent' => 2, 'lib' => '<500'),
array('id' => 6, 'parent' => 2, 'lib' => '>500'),
array('id' => 7, 'parent' => 0, 'lib' => 'Immo'),
array('id' => 8, 'parent' => 7, 'lib' => 'Location'),
array('id' => 9, 'parent' => 7, 'lib' => 'Achat'),
array('id' =>10, 'parent' => 7, 'lib' => 'Vente'),
);
$tree = new Tree($list);
$tree->dump();

?>

le resultat :

[ news]$ php -q tree.php
Node: root
Node: Auto/motos/bateaux
Node: Moto
Node: <500
Node: >500
Node: Voiture
Node: Bateau
Node: Immo
Node: Location
Node: Achat
Node: Vente



Avatar
Marc


D'avance Merci


je suis en train d'ecrire une classe qui devrait permettre de réaliser
cela. En fait c'est un ensemble de classes : Node qui est un container
composite et Tree qui supporte les fonctions de gestion de l'arbre.

j'espere terminer ce petit exercice de style dans la journée.

Avatar
Batman

le plus compact est sans doute en opposition avec réutilisabilité.
Pour etre réutilisable, le code doit présenter cette structure, ce
qui n'est pas le cas du code que tu as fourni :


C'est pas faux, en effet, à la réflexion j'aurais peut être du écrire
'didactique' (bien que je pense ne pas être un élève facile à
comprendre ... ;-)

voici les classes php que j'ai réalisé pour toi (et pour le fun) :
on notera en meme temps, l'arbre construit avec des références.
Si les objets sont copiés, rien ne fonctionne, attention a bien
garder le mécanisme des réferences.


Merci beaucoups ! Le jour ou je serais techniquement capable de reproduire
cet acte (de fun :-D ), je le referais !

<?php

error_reporting(E_ALL);

class Node{
var $id;


Errff, j'ai l'impression qu'il va falloir que je me mette aussi à
l'(orienté) objet.
--
Les fautes d'orthographes sont ma signature :-)
pour me répondre en BAL (mode antispam)
http://batman.dyndns.org/V2/Mail/?src=news.free

Avatar
Marc Quinton
Batman wrote:

Errff, j'ai l'impression qu'il va falloir que je me mette aussi à
l'(orienté) objet.


la plus grosse difficulté est simplement de discerner les vrai objets
et ses methodes (actions) d'objets fantaisistes qui risquent de mettre
ton application dans un triste état sur le plan de l'évolution et
du rendu des services.

par l'expérience (c'est tout de meme assez rapide), on arrive assez
rapidement a isoler les objets sous forme de classe. Puis au fur et
a mesure, dans un contexte assez simple, sans conception préalable
il est relativement rapide de creer qq chose qui tient a peu pres
la route.

le plus difficile est de commencer. Apres on ne peut plus s'arreter.

PS: petit signe discret pour les modérateurs ... (voir header).

Avatar
loufoque
Batman a dit le 14/01/2005 18:40:

Soit le tableau ci-dessous :

Id Parent Lib
1 0 Auto/motos/bateaux
2 1 Moto
3 1 voiture
4 1 bateau
5 2 <500 cm3
6 2 >500 cm3
7 0 Immobilier
8 7 location
9 7 achat
10 7 vente



Tes données proviennent sûrement d'une base de données.
Si c'est le cas, mieux vaut gérer ton arbre avec SQL, avec la technique
des "Nested Sets" par exemple.

Avatar
Batman

Batman a dit le 14/01/2005 18:40:

Soit le tableau ci-dessous :

Id Parent Lib
1 0 Auto/motos/bateaux
2 1 Moto
3 1 voiture
4 1 bateau
5 2 <500 cm3
6 2 >500 cm3
7 0 Immobilier
8 7 location
9 7 achat
10 7 vente



Tes données proviennent sûrement d'une base de données.
Si c'est le cas, mieux vaut gérer ton arbre avec SQL, avec la technique
des "Nested Sets" par exemple.


assurément, mes recherches ne faisait que pointer sur des personnes se
faisant insulter de gérer une gestion type 'arbo', via sql
mais une recherche sur 'Nested Sets' donne des résultats sympa, ex :
http://www.phpfrance.com/forums/sutra165035.php&sidü23d38c3fe7c847c8a97d0e6fa14806

mais je garde les 2 pistes, ne serait-ce que pour ma compréhension
personnelle !

--
Les fautes d'orthographes sont ma signature :-)
pour me répondre en BAL (mode antispam)
http://batman.dyndns.org/V2/Mail/?src=news.free


Avatar
Batman

PS: petit signe discret pour les modérateurs ... (voir header).


Je suis pas modérateur, mais vu le jour que l'on est aujourd'hui : 'joyeux
baptême' :-D
J'espère que les logiciels de pilotages sont sous autre chose que win :-DDDD

--
Les fautes d'orthographes sont ma signature :-)
pour me répondre en BAL (mode antispam)
http://batman.dyndns.org/V2/Mail/?src=news.free

Avatar
loufoque
Batman a dit le 18/01/2005 09:12:

assurément, mes recherches ne faisait que pointer sur des personnes se
faisant insulter de gérer une gestion type 'arbo', via sql
mais une recherche sur 'Nested Sets' donne des résultats sympa, ex :
http://www.phpfrance.com/forums/sutra165035.php&sidü23d38c3fe7c847c8a97d0e6fa14806


Il y a ce tutorial (qui n'est pas le meilleur, mais c'est le seul que je
connaisse en français - d'ailleurs la traduction me semble mauvaise, on
pourrait confondre avec les "Nested Intervals" qui fonctionnent avec des
rationnels)
http://sql.developpez.com/arborescence/