begin process at 2012 05 27 21:47:11
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > HIÉRARCHISATION D'UN TABLEAU PAR FONCTION RÉCURSIVE

HIÉRARCHISATION D'UN TABLEAU PAR FONCTION RÉCURSIVE


 Information sur la source

Note :
Aucune note
Catégorie :Astuces Classé sous :récursivité, hierarchie, parents, enfants Niveau :Débutant Date de création :14/01/2009 Date de mise à jour :18/01/2009 16:48:58 Vu / téléchargé :4 251 / 111

Auteur : foxmaster

Ecrire un message privé
Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

 Description

Cette fonction permet a partir d'un tableau (array) soit généré a la main soit comme dans l'exemple généré a partir d'une base de donnée
de trier les élément de maniere hiérarchique
parent
   enfant
      enfant de l'enfant
           etc....
la base de donnée est faite de la façon suivante:

id int(11) <== auto_increment (identifiant unique)
nom text <== nom de l'élement
niveau int(11) <== quelle position il a (pas obligatoire)
dependance int(11) <== id de l'objet parent (0 si il n'en a pas)


vous pouvez tester ici
http://foxmaster.info/recursivite/recursivite. php

et télécharger la source + BDD ici
http://foxmaster.info/telechargements/recursiv ite.zip



Source

  • <?php
  • //fonction récursive
  • //$td => tableau à traiter,
  • //$parent => va etre apelé pour chercher les element dépendant de l'élément précédemment traité
  • //$appelid => variable qui si définie définira l'id comme racine et cherchera les élement enfants a partir de ce point
  • function recurs($tb,$parent,$appelid,$newtab= array())
  • {
  • if(!empty($tb))
  • {//Pour chaque élément du tableau...
  • foreach($tb as $key => $value)
  • {
  • if (isset ($value['id'], $value['nom'], $value['niveau'], $value['dependance']))
  • {
  • if(!$appelid) //si on ne par pas d'un autre point
  • {
  • //si il n'y a pas de dépendance (racine)
  • if($value['dependance']==0 and $parent==0)
  • {
  • $newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
  • $newtab = recurs($tb,$value['id'],0,$newtab);
  • }
  • //si la fonction déja bouclé une premiere fois on cherche les objets enfant au parent appelé
  • if($parent!=0 and $value['dependance']==$parent)
  • {
  • $newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
  • $newtab = recurs($tb,$value['id'],0,$newtab);// et on rappelle la fonction
  • }
  • }
  • else
  • { // si la variable $appelid a été appelée
  • if($value['id']==$appelid) //on cherche l'élement correspondant qui fera office de racine
  • {
  • $newtab[]= array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
  • $newtab = recurs($tb,$value['id'],0,$newtab); // et on rapelle la fonction
  • }
  • }
  • }
  • }
  • }
  • return $newtab;
  • }
  • //création du tableau
  • $tb[] = array('id' => 1,'nom' => 'Fruits', 'niveau' => 1, 'dependance' => 0);
  • $tb[] = array('id' => 2,'nom' => 'L&eacute;gumes', 'niveau' => 1, 'dependance' => 0);
  • $tb[] = array('id' => 3,'nom' => 'Viandes', 'niveau' => 1, 'dependance' => 0);
  • $tb[] = array('id' => 4,'nom' => 'Poissons', 'niveau' => 1, 'dependance' => 0);
  • $tb[] = array('id' => 5,'nom' => 'Agrumes', 'niveau' => 2, 'dependance' => 1);
  • $tb[] = array('id' => 6,'nom' => 'Racines', 'niveau' => 2, 'dependance' => 2);
  • $tb[] = array('id' => 7,'nom' => 'Viandes Blanches', 'niveau' => 2, 'dependance' => 3);
  • $tb[] = array('id' => 8,'nom' => 'Viandes Rouges', 'niveau' => 2, 'dependance' => 3);
  • $tb[] = array('id' => 9,'nom' => 'Exotiques', 'niveau' => 2, 'dependance' => 1);
  • $tb[] = array('id' => 10,'nom' => 'De mer', 'niveau' => 2, 'dependance' => 4);
  • $tb[] = array('id' => 11,'nom' => 'Oranges', 'niveau' => 3, 'dependance' => 5);
  • $tb[] = array('id' => 12,'nom' => 'Carottes', 'niveau' => 3, 'dependance' => 6);
  • $tb[] = array('id' => 13,'nom' => 'Veau', 'niveau' => 3, 'dependance' => 7);
  • $tb[] = array('id' => 14,'nom' => 'Cheval', 'niveau' => 3, 'dependance' => 8);
  • $tb[] = array('id' => 15,'nom' => 'Gris&eacute;s', 'niveau' => 3, 'dependance' => 10);
  • $tb[] = array('id' => 16,'nom' => 'Fruits de la passion', 'niveau' => 3, 'dependance' => 9);
  • $tb[] = array('id' => 17,'nom' => 'Pommes de Terres', 'niveau' => 3, 'dependance' => 6);
  • $tb[] = array('id' => 18,'nom' => 'jaunes', 'niveau' => 4, 'dependance' => 17);
  • $tb[] = array('id' => 19,'nom' => 'rouges', 'niveau' => 4, 'dependance' => 17);
  • /********************************************/
  • $newtab = recurs($tb,0,0,''); // on appelle notre fonction de récursivité
  • echo '
  • <select name="choix_elements" onchange="window.location.href=\'?choix_elements=\'+this.value;">
  • <option value="0">S&eacute;lectionner</option>\n';
  • foreach($newtab as $key => $valnewtab) // on lis le nouveau tableau généré apres traitement de la fonction
  • {
  • $nom=$valnewtab['nom'];
  • if($key==0){$lvl0=$valnewtab['niveau'];}
  • if($valnewtab['niveau']>$lvl0 and $key!=0)
  • {
  • for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
  • {
  • $nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
  • }
  • }
  • echo ' <option value="'.$valnewtab['id'].'" ';
  • if($_GET['choix_elements']==$valnewtab['id']){echo 'selected';} //si get appelé et correspond a l'élément traité on di qu'il est sélectionné
  • echo'>'.$nom.'</option>\n';
  • }
  • echo '</select>
  • ';
  • if(isset($_GET['choix_elements']))
  • {$newtab = recurs($tb,0,$_GET['choix_elements'],'');}
  • else
  • {$newtab = recurs($tb,0,0,'');}
  • echo '<br />
  • ';
  • foreach($newtab as $key => $valnewtab)
  • {
  • $nom=$valnewtab['nom'];
  • if($key==0){$lvl0=$valnewtab['niveau'];}
  • if($valnewtab['niveau']>$lvl0 and $key!=0)
  • {
  • for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
  • {
  • $nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
  • }
  • }
  • echo $nom.'<br />';
  • //si l'on ne souhaite pas inclure l'élément précédemment sélectionné il suffirait de mettre
  • //if($valnewtab['id']!=$_GET['choix_elements']){echo '$valnewtab[nom] (id : $valnewtab[id])<br />';}
  • }
  • ?>
<?php
//fonction récursive
//$td => tableau à traiter, 
//$parent => va etre apelé pour chercher les element dépendant de l'élément précédemment traité
//$appelid => variable qui si définie définira l'id comme racine et cherchera les élement enfants a partir de ce point
function recurs($tb,$parent,$appelid,$newtab= array())
{
	if(!empty($tb))
	{//Pour chaque élément du tableau...
		foreach($tb as $key => $value)
		{
			if (isset ($value['id'], $value['nom'], $value['niveau'], $value['dependance'])) 
			{
				if(!$appelid) //si on ne par pas d'un autre point
				{
					//si il n'y a pas de dépendance (racine) 
					if($value['dependance']==0 and $parent==0)
					{
						$newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab);
					}
					//si la fonction déja bouclé une premiere fois on cherche les objets enfant au parent appelé
					if($parent!=0 and $value['dependance']==$parent)
					{
						$newtab[] = array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab);// et on rappelle la fonction
					}
				}
				else
				{ // si la variable $appelid a été appelée
					if($value['id']==$appelid) //on cherche l'élement correspondant qui fera office de racine
					{
						$newtab[]= array('id' => $value['id'],'nom' => $value['nom'], 'niveau' => $value['niveau'], 'dependance' => $value['dependance']);
						$newtab = recurs($tb,$value['id'],0,$newtab); // et on rapelle la fonction 
					}
				}
			}
		}
	}
	return $newtab;
}
//création du tableau
$tb[] = array('id' => 1,'nom' => 'Fruits', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 2,'nom' => 'L&eacute;gumes', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 3,'nom' => 'Viandes', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 4,'nom' => 'Poissons', 'niveau' => 1, 'dependance' => 0);
$tb[] = array('id' => 5,'nom' => 'Agrumes', 'niveau' => 2, 'dependance' => 1);
$tb[] = array('id' => 6,'nom' => 'Racines', 'niveau' => 2, 'dependance' => 2);
$tb[] = array('id' => 7,'nom' => 'Viandes Blanches', 'niveau' => 2, 'dependance' => 3);
$tb[] = array('id' => 8,'nom' => 'Viandes Rouges', 'niveau' => 2, 'dependance' => 3);
$tb[] = array('id' => 9,'nom' => 'Exotiques', 'niveau' => 2, 'dependance' => 1);
$tb[] = array('id' => 10,'nom' => 'De mer', 'niveau' => 2, 'dependance' => 4);
$tb[] = array('id' => 11,'nom' => 'Oranges', 'niveau' => 3, 'dependance' => 5);
$tb[] = array('id' => 12,'nom' => 'Carottes', 'niveau' => 3, 'dependance' => 6);
$tb[] = array('id' => 13,'nom' => 'Veau', 'niveau' => 3, 'dependance' => 7);
$tb[] = array('id' => 14,'nom' => 'Cheval', 'niveau' => 3, 'dependance' => 8);
$tb[] = array('id' => 15,'nom' => 'Gris&eacute;s', 'niveau' => 3, 'dependance' => 10);
$tb[] = array('id' => 16,'nom' => 'Fruits de la passion', 'niveau' => 3, 'dependance' => 9);
$tb[] = array('id' => 17,'nom' => 'Pommes de Terres', 'niveau' => 3, 'dependance' => 6);
$tb[] = array('id' => 18,'nom' => 'jaunes', 'niveau' => 4, 'dependance' => 17);
$tb[] = array('id' => 19,'nom' => 'rouges', 'niveau' => 4, 'dependance' => 17);
/********************************************/
$newtab = recurs($tb,0,0,''); // on appelle notre fonction de récursivité
echo '
<select name="choix_elements" onchange="window.location.href=\'?choix_elements=\'+this.value;">
	<option value="0">S&eacute;lectionner</option>\n';
	foreach($newtab as $key => $valnewtab) // on lis le nouveau tableau généré apres traitement de la fonction
	{
		$nom=$valnewtab['nom'];
		if($key==0){$lvl0=$valnewtab['niveau'];}
		if($valnewtab['niveau']>$lvl0 and $key!=0) 
		{
			for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
			{
				$nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
			}
		}
		echo '	<option value="'.$valnewtab['id'].'" ';
		if($_GET['choix_elements']==$valnewtab['id']){echo 'selected';} //si get appelé et correspond a l'élément traité on di qu'il est sélectionné
		echo'>'.$nom.'</option>\n';
	}
echo '</select>
';
if(isset($_GET['choix_elements']))
{$newtab = recurs($tb,0,$_GET['choix_elements'],'');}
else
{$newtab = recurs($tb,0,0,'');}
echo '<br />
';
foreach($newtab as $key => $valnewtab)
{				
	$nom=$valnewtab['nom'];
	if($key==0){$lvl0=$valnewtab['niveau'];}
	if($valnewtab['niveau']>$lvl0 and $key!=0) 
	{
		
		for($nv=0;$nv<($valnewtab['niveau']-$lvl0);$nv++)//permet d'ajouter des espaces
		{
			$nom= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$nom;
		}
	}
	echo $nom.'<br />';
	//si l'on ne souhaite pas inclure l'élément précédemment sélectionné il suffirait de mettre 
	//if($valnewtab['id']!=$_GET['choix_elements']){echo '$valnewtab[nom] (id : $valnewtab[id])<br />';}
}
?>


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

14 janvier 2009 00:53:28 :
juste fonction, l'exemple est dans le zip
14 janvier 2009 13:53:38 :
modif suite commentaire
14 janvier 2009 13:57:35 :
modification suite commentaire.
14 janvier 2009 14:22:24 :
correction après test modifications
14 janvier 2009 18:31:00 :
modification avec intégration exemple sans bdd
14 janvier 2009 18:33:31 :
nettoyage code
14 janvier 2009 22:14:19 :
changement titre
15 janvier 2009 17:09:04 :
correction bug "Notice: undefined index:" nettoyage code (quotes simples cotes)
18 janvier 2009 16:48:58 :
isset corrigé

 Sources du même auteur

Source avec Zip Source avec une capture PUBLIPOSTAGE DOCUMENTS WORDS(AU FORMAT RTF) A PARTIR D'UNE B...
Source avec Zip Source avec une capture TCHAT COMBINANT JAVASCRIPT/PHP (AUCUN APPLET JAVA OU AUTRE T...

 Sources de la même categorie

AFFICHÉ SUR UN TABLEAU AVEC PAGINATION ET BASE DE DONNÉES par stormxp
Source avec Zip Source avec une capture GENERATEUR D'ONGLET DE NAVIGATION PHP par pos123
FORMATER UN LIEN YOUTUBE, DAILYMOTION OU VIMEO POUR L'UTILIS... par kgb93
Source avec Zip Source avec une capture PAGINATION + FICHIER CSS par profdi
Source avec Zip Source avec une capture SYSTEME D'AUTHENTIFICATION PHP AVEC PROTÉCTION KEYLOGGER par mtrix000

 Sources en rapport avec celle ci

GÉNÉRATION RÉCURSIVE D'UNE ARBORESCENCE DE RÉPERTOIRES par webdeb
Source avec Zip [FONCTION RÉCURSIVE] DETERMINER LE PGDC DE DEUX NOMBRES par Palleas_44
Source avec Zip GALLERIE D'IMAGE CONSTRUITE PAR APPELS RÉCURSIFS DANS UN RÉP... par satanik_mike
CRÉATION D'UNE ARBORESCENCE par Charles Racaud
LISTER LES FICHIERS D'UN DOSSIER ET EN FAIRE DES LIENS ( MEI... par Evangun

Commentaires et avis

Commentaire de Teclis01 le 14/01/2009 09:35:08

_un foreach sans if(!empty($aArray)) pas très élégant...
_un global ... encore moins élégant...
_Pas d'exemple d'utilisation
_$parent=="" or $parent==0 très moche ^_^ Soit il a un id>0 auquel cas il a un parent soit non pq testes tu la chaine vide?

A vos claviers!

Commentaire de foxmaster le 14/01/2009 14:00:42

Merci pour ces commentaires  j'ai appliqué certaines des modifs données
(if(!empty) et les parent inutiles,
concernant le global, je ne vois pas d'autre solution pour récupérer de nouveau sous forme de tableau filtrés les données.

concernant l'exemple
il y en a un ici
http://foxmaster.info/recursivite/recursivite.php
comme précisé dans la partie supérieure

Commentaire de codefalse le 14/01/2009 14:29:23 administrateur CS

et à ta place je testerai aussi si le tableau donné respecte bien la demande (si les diverses clées (id, nom, niveau, dependance) sont présentent avec un petit isset :)

Commentaire de Teclis01 le 14/01/2009 15:06:08

pour ton global, suffit de lui passer en param d'entrée à ta fonction récursive.
function recurs($tb,$parent,$appelid,$newtab=array())
et tu le retournes.
ensuite tu changes pas sont type en cours de route (Ligne 1 c'est un string vide puis devient un array)

Commentaire de foxmaster le 14/01/2009 18:35:17

j'ai de nouveau apporté les modifs de codefalse et teclis01
si vous soyez autre chose...?
j'ai intégré un exemple.

Commentaire de Flachy Joe le 14/01/2009 19:06:31

Le titre de la source ne correspond pas au contenu, il devrait donner une idée de ce qu'on va trouver.

"Hiérarchisation d'un tableau par une application de la récursivité", ou quelque chose comme ça, conviendrai mieux il me semble.

Sinon bonne idée, ça doit pouvoir être utile.

Commentaire de codefalse le 15/01/2009 00:51:57 administrateur CS

La beauté de isset est que tu peux lui passer n paramètres à tester, dans ton cas :

if (isset ($value['id'], $value['nom'], $value['niveau'], $value['dependance'])) {
  // ..
}

et remplace tous les " (double quotes) par des ' (simple quotes), c'est plus performant.

Commentaire de crazygogo le 15/01/2009 09:45:18

Notice: Undefined index: choix_elements

Commentaire de josselinbonnin le 24/02/2010 01:31:46

salut

moi perso jai pas les &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

donc jai fait :

$newtab = recurs($tb,0,0,'');
echo "
<select name=\"choix_elements\">
<option value=\"0\">S&eacute;lectionner</option>\n";

foreach($newtab as $key => $valnewtab) {

$nom=$valnewtab['nom'];
if($key==0){$lvl0=$valnewtab['niveau'];}
$style=10*$valnewtab['niveau'];

echo "<option style=\"padding-left:".$style."px;\" value=\"".$valnewtab['id']."\"";

if($_GET['choix_elements']==$valnewtab['id']){echo "selected";}

echo">".$nom."</option>\n";

}
echo "</select>";

Commentaire de josselinbonnin le 24/02/2010 01:42:58

re salut

et puis juste un détail mais éviter de mettre des echo partout
juste un a la fin sa suffit

$newtab = recurs($tb,0,0,'');
$select.="<select name=\"choix_elements\">\n";
$select.="<option value=\"0\">S&eacute;lectionner</option>\n";

foreach($newtab as $key => $valnewtab) {

$nom=$valnewtab['nom'];
if($key==0){$lvl0=$valnewtab['niveau'];}
$style=10*$valnewtab['niveau'];

$select .="<option style=\"padding-left:".$style."px;\" value=\"".$valnewtab['id']."\"";

if($_GET['choix_elements']==$valnewtab['id']){echo "selected";}

$select.=">".$nom."</option>\n";

}
$select.="</select>";


echo $select;

Commentaire de Anardil le 22/07/2010 18:47:33

Salut,

J'ai testé ta fonction sur mes catégories. 70 catégories, 3 niveaux de catégories.
Ta fonction est chronophage. J'ai eu un bon Memory Limit.
Il faudrait la revoir un peu :p

Commentaire de foxmaster le 22/07/2010 22:19:00

Bonjour,

j'avoue ne pas avoir essayé de pousser la récursivité à un si grand niveau, ta base est-elle bien optimisée?

la requete faisant un appel de toutes les données de la base, peut etre aussi modifier cette requete pour qu'elle ne sélectionne que les champs nécessaires.

bien que mon exemple montre tous les sous éléments , je ne pense pas que l'on ai à montrer tout d'un coup.

je n'ai pas vraiment d'idée et a vrai dire cela fait longtemps que je n'ai pas codé.. mais si tu as une piste, un indice ou des idées, expose les ;)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

récursivité quand tu me tiens [ par livingdead ] j'ai une requete qui traite de catégrorie, et ses catégories peuvent avoir une catégorie parent qui peut elle aussi avoir un parent etc .............. Variables [ par simpso95 ] Bonsoir à tous.Je me lance dans la grande famille du....php. Déjà je bute sur quelques problème.Afin d'apprendre le php 5, je construis un "jeu" éduca affiche les resutats de mes requètes [ par msi079 ] salut . j'ai une base de donnée qui contient la table victime (matricule,questionnaire,nom,region,village,tel) enfant(id_enfant,matricule,nom1,lien1,


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,484 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales