Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
419 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Trier une array - arbre

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Trier une array - arbre

n°1690292
ZeBix
edit > preview
Posté le 21-02-2008 à 17:47:12  profilanswer
 

Bonjour tous,  
 
Avec une requête SQL j'obtiens une array de ce type :  

Code :
  1. $myarray[0]["id"]=1;
  2. $myarray[0]["parent"]=0;
  3. $myarray[1]["id"]=2;
  4. $myarray[1]["parent"]=0;
  5. $myarray[2]["id"]=3;
  6. $myarray[2]["parent"]=1;
  7. $myarray[3]["id"]=4;
  8. $myarray[3]["parent"]=1;
  9. $myarray[4]["id"]=5;
  10. $myarray[4]["parent"]=2;
  11. $myarray[5]["id"]=6;
  12. $myarray[5]["parent"]=1;
  13. $myarray[6]["id"]=7;
  14. $myarray[6]["parent"]=3;


 
Je voudrais trier cette array par ID, chacun suivi immédiatement de ses enfants et cela de manière récursive.
 
Dans l'exemple ci-dessus, l'array nouvellement triée que je voudrais obtenir aurait donc les valeurs de $myarray dans cette ordre :  
0 - 2 - 6 - 3 - 5 - 1 - 4  
c'est-à-dire l'arbre d'IDs représenté dans l'array  :

IDs :  
+ 1
| + 3
| | + 7
| +  4
| +  6
+ 2
| + 5

A noter que 3, 4 et 6 peuvent être dans n'importe quel ordre puisque tous enfants de 1.
 
 
Tout d'abord j'ai essayé de trier ma requête SQL, pour éviter de devoir jouer avec des array ...  mais ça semble impossible en une seule requête, même avec des requêtes imbriquées (puisque chaque ligne exige de voir si son parent a déjà été sélectionné, ou pire, son parent peut très bien se trouver "après" dans la table)... Je peux évidemment faire des requêtes récursives via scripts PHP, genre je prends tous les ID dont le parent est 0, puis un par un je sélectionne ses enfants, etc. etc. mais ça va me faire trop de requêtes, j'en voudrais une seule (rien que dans l'exemple ultra simplifié ci-dessus j'aurais 8 requêtes si je compte bien)
 
J'ai essayé d'explorer la voie avec multisort() mais je ne vois vraiment pas quoi faire, je suis un peu bloqué ..
 
Ce que je veux faire ne me semble pas si difficile, pourtant je ne trouve rien de véritablement probant dans les miyyons d'articles sur le PHP array sorting sur le web ...  
 
quelqu'un aurait-il une piste ?  
 
En vous r'merciant  :hello:  
 

mood
Publicité
Posté le 21-02-2008 à 17:47:12  profilanswer
 

n°1690420
theredled
● REC
Posté le 22-02-2008 à 01:15:22  profilanswer
 

Erf :D

 

Moi, là comme ça, je ferais ça par insertions :
- tu insères d'abord les éléments dont le parent est 0
- ensuite pour chacun tu cherches s'il a des enfants, si oui tu les insère juste apres leur parent
- c'est reparti pour un tour etc

 

Tout ça avec un tableau de départ et un tableau d'arrivée, et tu "déplace" les éléments. Le truc est fini quand le tableau de départ est vide...

 

Et pour te faciliter la tache, tu fais à la base un tableau de la forme
"id" => "parent" et pas "indexquisertarien" => ["id", "parent"]

 

Pour ce dernier point, je pense que ça peut bien t'aider, pour le premier (la méthode de tri), je sais pas si c'est le mieux optimisé...


Message édité par theredled le 22-02-2008 à 01:16:13

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
n°1690491
ZeBix
edit > preview
Posté le 22-02-2008 à 10:21:20  profilanswer
 

Merci pour ta réponse,

 
Citation :

Moi, là comme ça, je ferais ça par insertions :
- tu insères d'abord les éléments dont le parent est 0
- ensuite pour chacun tu cherches s'il a des enfants, si oui tu les insère juste apres leur parent
- c'est reparti pour un tour etc

 

La manière dont fonctionne un "fetch" dans un result set SQL me fait dire que cette solution n'est pas possible ... elle demanderait que PHP ait des pointeurs qui me permettent de me ballader dans le result set et ça, malheureusement, ça n'existe pas :(

 
Citation :

Et pour te faciliter la tache, tu fais à la base un tableau de la forme
"id" => "parent" et pas "indexquisertarien" => ["id", "parent"]

 

ça en revanche me paraît un excellent commencement, vrai que l' "indexquisertàrien", que j'obtenais tout simplement parce que je faisais un array_push() pour peupler $myarray, est totalement inutile et ne va pas faciliter la chose ...

 

j'aurais donc un truc du genre :

Code :
  1. $myarray[1]=0;
  2. $myarray[2]=0;
  3. $myarray[3]=1;
  4. $myarray[4]=1;
  5. $myarray[5]=2;
  6. $myarray[6]=1;
  7. $myarray[7]=3;
 

et je voudrais toujours obtenir, donc, l'ordre  1 - 3  - 7 - 4  - 6 -  2 - 5

Message cité 1 fois
Message édité par ZeBix le 22-02-2008 à 10:21:38
n°1690577
theredled
● REC
Posté le 22-02-2008 à 11:48:42  profilanswer
 

ZeBix a écrit :

La manière dont fonctionne un "fetch" dans un result set SQL me fait dire que cette solution n'est pas possible ... elle demanderait que PHP ait des pointeurs qui me permettent de me ballader dans le result set et ça, malheureusement, ça n'existe pas :(


Ben tu mets ton result set dans un tableau classique avant et voilou :??: j'avais cru comprendre que tu le faisais déja...

 

De toute façon tu es obligé si tu veux le réindexer.


Message édité par theredled le 22-02-2008 à 11:50:05

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
n°1690658
ZeBix
edit > preview
Posté le 22-02-2008 à 13:51:14  profilanswer
 

Heu oui en fait , je n'avais pas bien compris ta réponse, c'est clair maintenant :)
 
Merci pour le tuyau je pense que ça fera l'affaire ! Pas évident parce qu'il faut bien tricoter (merci pour l'idée des index qui sont les ID, ça accélère le bidule) mais le principal c'est que j'ai mon résultat...  
 
Si quelqu'un a une idée plus optimisée, je suis également preneur :jap:

n°1690674
anapajari
s/travail/glanding on hfr/gs;
Posté le 22-02-2008 à 14:17:06  profilanswer
 

http://dev.mysql.com/tech-resource [...] -data.html


---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1690691
theredled
● REC
Posté le 22-02-2008 à 14:29:54  profilanswer
 

Voila l'homme qu'il nous fallait [:kbchris]


Message édité par theredled le 22-02-2008 à 14:30:15

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
n°1690747
ZeBix
edit > preview
Posté le 22-02-2008 à 15:16:46  profilanswer
 

Merci pour le link, anapajari, mais je vois deux solutions proposées sur cette page :

 

- Une qui requiert de connaître quelle est la profondeur maximale de l'arbre (puisqu'il faut un self join pour chaque niveau), et dans ma structure de données cette profondeur est totalement dynamique.
- Une qui requiert de changer complètement l'organisation des données et l'insertion de celles-ci, pour utiliser les "nodes" left et right. Le modèle est du reste très intéressant mais malheureusement comme beaucoup de concepteurs de scripts, je n'ai pas la mainmise sur tous les aspects de mon S.I., et ne peux donc pas procéder à de tels changements ...
 

Message cité 2 fois
Message édité par ZeBix le 22-02-2008 à 15:17:20
n°1690778
babasss
Posté le 22-02-2008 à 15:43:18  profilanswer
 

ZeBix a écrit :


- Une qui requiert de connaître quelle est la profondeur maximale de l'arbre (puisqu'il faut un self join pour chaque niveau), et dans ma structure de données cette profondeur est totalement dynamique.


Ne peux-tu pas trouver un moyen de calculer cette profondeur ?

 

edit: en faisant SELECT count( DISTINCT id_parent) tu obtiens le nb de niveau hiérarchique...

 

Message cité 2 fois
Message édité par babasss le 22-02-2008 à 15:49:53

---------------
Feedback : http://forum.hardware.fr/hfr/Achat [...] 2666_1.htm
n°1690799
anapajari
s/travail/glanding on hfr/gs;
Posté le 22-02-2008 à 15:59:06  profilanswer
 

ZeBix a écrit :

Merci pour le link, anapajari, mais je vois deux solutions proposées sur cette page :  
 
- Une qui requiert de connaître quelle est la profondeur maximale de l'arbre (puisqu'il faut un self join pour chaque niveau), et dans ma structure de données cette profondeur est totalement dynamique.
- Une qui requiert de changer complètement l'organisation des données et l'insertion de celles-ci, pour utiliser les "nodes" left et right. Le modèle est du reste très intéressant mais malheureusement comme beaucoup de concepteurs de scripts, je n'ai pas la mainmise sur tous les aspects de mon S.I., et ne peux donc pas procéder à de tels changements ...  


Non y'a pas 2 solutions, y'a une problématique "les données hierarchisées" en sql.
 
Ensuite une présentation des listes adjacentes (la solution que tu utilises comme beaucoup de gens) qui insiste sur les défauts de celle-ci. Defauts que tu as toi même constaté puisque tu es bloqué sur le problème de profondeur.
 
Enfin la solution des "nested set" qui réponds parfaitement à ton besoin et présente de nombreux avantages (surtout en terme de rapidité).  
C'est, ama, LA solution a utilisé dans ce genre de situation.
Quand tu dis "je n'ai pas la main sur le SI" ça veut dire que tu n'as pas le droit de modifier la structure d'une table :??:
 
Et si tu peux vraiment pas, alors la "tripatouillage" via un truc récursif en php reste certainement la meilleure solution.


---------------
Software and cathedrals are much the same - first we build them, then we pray.
mood
Publicité
Posté le 22-02-2008 à 15:59:06  profilanswer
 

n°1690800
ZeBix
edit > preview
Posté le 22-02-2008 à 15:59:11  profilanswer
 

babasss a écrit :

edit: en faisant SELECT count( DISTINCT id_parent) tu obtiens le nb de niveau hiérarchique...

 

Gné  :heink:

 

ID : 1 - ID_parent : 0
ID : 2 - ID_parent : 0
ID : 3 - ID_parent : 0
ID : 4 - ID_parent : 1
ID : 5 - ID_parent : 2
ID : 6 - ID_parent : 3

 

Select count (distinct ID_parent) --> 4
Prodondeur de niveau : 2

 


anapajari a écrit :


Enfin la solution des "nested set" qui réponds parfaitement à ton besoin et présente de nombreux avantages (surtout en terme de rapidité).
C'est, ama, LA solution a utilisé dans ce genre de situation.
Quand tu dis "je n'ai pas la main sur le SI" ça veut dire que tu n'as pas le droit de modifier la structure d'une table :??:

 

Et si tu peux vraiment pas, alors la "tripatouillage" via un truc récursif en php reste certainement la meilleure solution.

 

La structure de la table je pense pouvoir la modifier, mais la manière dont les informations sont entrées dedans non. Donc si la solution des nested sets demande des informations complémentaires, je peux probablement changer celles qui existent déjà via des scripts, mais il va falloir changer tout le processus d'encodage (la structure hiérarchisée sur laquelle je travaille étant en évolution) et ça c'est une autre paire de manches ... :/

 

Enfin quoi qu'il en soit pour toute structure ultérieure j'analyserai ce modèle avec attention car ça semble être le top indeed ...

 

Message cité 1 fois
Message édité par ZeBix le 22-02-2008 à 16:06:52
n°1690802
theredled
● REC
Posté le 22-02-2008 à 16:00:03  profilanswer
 

babasss a écrit :


Ne peux-tu pas trouver un moyen de calculer cette profondeur ?

 

edit: en faisant SELECT count( DISTINCT id_parent) tu obtiens le nb de niveau hiérarchique...

 



Nop, si tu as 1400 parents de niveau 1 sans enfants, ça te retournera 1400, par ex :o

 

[:grilled]


Message édité par theredled le 22-02-2008 à 16:00:33

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
n°1690820
babasss
Posté le 22-02-2008 à 16:13:00  profilanswer
 

ZeBix a écrit :


Gné  :heink:  
 
ID : 1 - ID_parent : 0
ID : 2 - ID_parent : 0
ID : 3 - ID_parent : 0
ID : 4 - ID_parent : 1
ID : 5 - ID_parent : 2
ID : 6 - ID_parent : 3
 
Select count (distinct ID_parent) --> 4
Prodondeur de niveau : 2


Sauf que dans ce cas, la profondeur est de 3 (car il faut compter 0 qui est un niveau malgré lui). De toutes facons, ca ne change rien => je m'ai trompé  [:sisicaivrai]


Message édité par babasss le 22-02-2008 à 16:13:22

---------------
Feedback : http://forum.hardware.fr/hfr/Achat [...] 2666_1.htm

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Trier une array - arbre

 

Sujets relatifs
trier le resultat d un foreachCompter dans un array
[AS3] Positionner des pieces a l'aide d'un Array[PHP] Erreur: Cannot use a scalar value as an array
sql trier les résultats par ordre déterminéalgorithme:arbre binaire de recherche
trier après une requète (résolu)array un peu spécial (mysql inside)
Besoin d'aide sur un conteneur pour arbre binaire[Résolu] Supprimer une ligne d'un array sans trier ?
Plus de sujets relatifs à : Trier une array - arbre


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR