Trier une array - arbre - PHP - Programmation
Marsh Posté le 22-02-2008 à 01:15:22
Erf
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é...
Marsh Posté le 22-02-2008 à 10:21:20
Merci pour ta réponse,
Citation : Moi, là comme ça, je ferais ça par insertions : |
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 |
ç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 :
|
et je voudrais toujours obtenir, donc, l'ordre 1 - 3 - 7 - 4 - 6 - 2 - 5
Marsh Posté le 22-02-2008 à 11:48:42
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.
Marsh Posté le 22-02-2008 à 13:51:14
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
Marsh Posté le 22-02-2008 à 14:17:06
http://dev.mysql.com/tech-resource [...] -data.html
Marsh Posté le 22-02-2008 à 14:29:54
Voila l'homme qu'il nous fallait
Marsh Posté le 22-02-2008 à 15:16:46
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 ...
Marsh Posté le 22-02-2008 à 15:43:18
ZeBix 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...
Marsh Posté le 22-02-2008 à 15:59:06
ZeBix a écrit : Merci pour le link, anapajari, mais je vois deux solutions proposées sur cette page : |
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.
Marsh Posté le 22-02-2008 à 15:59:11
babasss a écrit : edit: en faisant SELECT count( DISTINCT id_parent) tu obtiens le nb de niveau hiérarchique... |
Gné
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 :
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 ...
Marsh Posté le 22-02-2008 à 16:00:03
babasss a écrit :
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
Marsh Posté le 22-02-2008 à 16:13:00
ZeBix a écrit : |
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é
Marsh Posté le 21-02-2008 à 17:47:12
Bonjour tous,
Avec une requête SQL j'obtiens une array de ce type :
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