Tableau à trier en fct de deux champs

Tableau à trier en fct de deux champs - PHP - Programmation

Marsh Posté le 18-07-2006 à 10:45:06    

uiop,
 
J'ai un tableau avec plusieurs entrées du genre :

Code :
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [COD_PRODUIT] => PE011
  6.             [COD_TYPE_LOT] =>
  7.             [NUM_LOT] => 635E16124614
  8.             [NOM_PRODUIT] => CROISSANT
  9.             [ETA_ROGNURE] => 0
  10.             [niveau] => 0
  11.             [lot_pere] => 635E16124614
  12.         )
  13.     [1] => Array
  14.         (
  15.             [COD_PRODUIT] => PE011
  16.             [COD_TYPE_LOT] =>
  17.             [NUM_LOT] => 635E16124615
  18.             [NOM_PRODUIT] => CROISSANT
  19.             [ETA_ROGNURE] => 0
  20.             [niveau] => 0
  21.             [lot_pere] => 635E16124615
  22.         )
  23.     [2] => Array
  24.         (
  25.             [COD_PRODUIT] => PE011
  26.             [COD_TYPE_LOT] =>
  27.             [NUM_LOT] => 635E16124616
  28.             [NOM_PRODUIT] => ingrédient quelconque
  29.             [ETA_ROGNURE] => 0
  30.             [niveau] => 1
  31.             [lot_pere] => 635E16124614
  32.         )


 
Je n'ai mis que les trois premiers mais la liste est longue. Il n'est donc pas trié.
Je le remplie par niveau, je commence à chercher les informations de ma bdd pour le niveau 0, ensuite, je boucle sur ce niveau 0 pour voir s'il y a un sous niveau, le 1 et ainsi de suite. Donc le tableau a comme entrée au début, le niveau 0, ensuite le niveau 1, niveau 2, ...
Déjà, est-ce une bonne idée ou ne pourrait on pas le trier à la volée ?
 
Si non, comment pourrais je le trier par la suite ?
J'ai utilisé array_multisort() ou sort() mais sans résultat.
 
Si quelqu'un a une idée. Merci.


Message édité par NerOcrO le 18-07-2006 à 11:00:04
Reply

Marsh Posté le 18-07-2006 à 10:45:06   

Reply

Marsh Posté le 18-07-2006 à 10:50:51    

Au lieu de faire un méga tableau de tableaux, conserve des tableaux indépendants mais parallèles et utilise array_multisort(). :o

Reply

Marsh Posté le 18-07-2006 à 10:51:49    

déjà si ça remonte de ta bdd pourquoi ne pas utiliser un order dans ta requête de select???
 
Ensuite si ce n'est pas possible, c'est exactement array_multisort dont tu as besoin, l'exemple 3 de la doc ( Example 3. Sorting database results)  réponds entièrement à ta question: http://fr.php.net/array_multisort

Reply

Marsh Posté le 18-07-2006 à 11:08:02    

anapajari a écrit :

déjà si ça remonte de ta bdd pourquoi ne pas utiliser un order dans ta requête de select???
 
Ensuite si ce n'est pas possible, c'est exactement array_multisort dont tu as besoin, l'exemple 3 de la doc ( Example 3. Sorting database results)  réponds entièrement à ta question: http://fr.php.net/array_multisort


 
J'ai une requête par niveau et je ne connais pas à l'avance le dernier niveau donc je ne peux pas faire comme tu dis.
 
Je connais bien cet exemple mais il ne convient pas dans mon cas car ma "clef" est faite de deux champs alors que array_multisort ne fonctionne que sur un champ.
Dans l'exemple que j'ai donné, le multisort a été effectué car j'ai rangé par niveau et ensuite par lot_pere alors que je voudrais qu'il range par niveau ET lot_pere en même temps ce qui donnerait que l'indice 2 de mon tableau serait à la place de l'indice 1.
 
Ouais je sais, c'est relou les tableaux :p

Reply

Marsh Posté le 18-07-2006 à 11:10:12    

Hermes le Messager a écrit :

Au lieu de faire un méga tableau de tableaux, conserve des tableaux indépendants mais parallèles et utilise array_multisort(). :o


 
Effectivement, ça serait une bonne idée mais je ne connais pas à l'avance combien j'aurai de tableau, tout est à la volée et c'est du récursif.
Peut on créer des tableaux à la volée et les réutiliser après ?
Du genre, $tab1, $tab2, $tab3, ...

Reply

Marsh Posté le 18-07-2006 à 11:14:28    

NerOcrO a écrit :

Effectivement, ça serait une bonne idée mais je ne connais pas à l'avance combien j'aurai de tableau, tout est à la volée et c'est du récursif.
Peut on créer des tableaux à la volée et les réutiliser après ?
Du genre, $tab1, $tab2, $tab3, ...


 
Oui c'est possible, tu les crés à la volée avec des ${'non_tableau'.$num} = array() et ensuite, tu construis via une boucle ton instruction PHP array_multisort()  avec concaténation etc... Puis tu exécutes cette instruction via eval().
 
Ouai, c'est de la folie, mais ça marche. [:petrus75]


Message édité par Hermes le Messager le 18-07-2006 à 11:14:47
Reply

Marsh Posté le 18-07-2006 à 11:33:42    

bin fait un usort alors ça triera exactement comme tu le désires alors [:spamafote]
un truc dans le genre:

Code :
  1. function cmp($a, $b){
  2.   if ( $a['niveau'] == $b['niveau']){
  3.     if ( $a['lot_pere'] == $b['lot_pere']){
  4.       return 0;
  5.     } else {
  6.       return ($a['lot_pere'] < $b['lot_pere']) ? -1 : 1;
  7.     }
  8.   } else {
  9.     return ($a['niveau'] < $b['niveau']) ? -1 : 1;
  10.   }
  11. }


Que tu utilises comme ça:

Code :
  1. usort($tableau, "cmp" );

Message cité 1 fois
Message édité par anapajari le 18-07-2006 à 11:34:23
Reply

Marsh Posté le 18-07-2006 à 11:38:35    

anapajari a écrit :

bin fait un usort alors ça triera exactement comme tu le désires alors [:spamafote]
un truc dans le genre:

Code :
  1. function cmp($a, $b){
  2.   if ( $a['niveau'] == $b['niveau']){
  3.     if ( $a['lot_pere'] == $b['lot_pere']){
  4.       return 0;
  5.     } else {
  6.       return ($a['lot_pere'] < $b['lot_pere']) ? -1 : 1;
  7.     }
  8.   } else {
  9.     return ($a['niveau'] < $b['niveau']) ? -1 : 1;
  10.   }
  11. }


Que tu utilises comme ça:

Code :
  1. usort($tableau, "cmp" );



 
Oui, j'étais en train de bosser dessus aussi :p
Ta fonction ne fonctionne pas (encore) mais j'y travaille !
 
Le but du jeu est d'avoir le niveau 0, puis le niveau 1, puis le niveau 2, ... du même lot père et ces mêmes niveaux peuvent avoir aussi des sous niveau d'où la complexité du truc.

Message cité 1 fois
Message édité par NerOcrO le 18-07-2006 à 11:41:53
Reply

Marsh Posté le 18-07-2006 à 11:57:24    

NerOcrO a écrit :

Oui, j'étais en train de bosser dessus aussi :p
Ta fonction ne fonctionne pas (encore) mais j'y travaille !


Tututututuuuu ma fonction fonctionne très bien :o

Code :
  1. $arr = array(
  2. array( 'niveau' => 4, 'lot_pere' => 'B'),
  3. array( 'niveau' => 4, 'lot_pere' => 'A'),
  4. array( 'niveau' => 2, 'lot_pere' => 'A'),
  5. array( 'niveau' => 1, 'lot_pere' => 'A'),
  6. );
  7. usort($arr, 'cmp');
  8. print_r($arr);


Donne  

Array
(
    [0] => Array
        (
            [niveau] => 1
            [lot_pere] => A
        )
 
    [1] => Array
        (
            [niveau] => 2
            [lot_pere] => A
        )
 
    [2] => Array
        (
            [niveau] => 4
            [lot_pere] => A
        )
 
    [3] => Array
        (
            [niveau] => 4
            [lot_pere] => B
        )
 
)


Maintenant ça trie peut-être pas dans l'ordre que tu voulais, mais je n'ai toujours pas compris quel était cet ordre :o ( Mais si c'est lot_pere qui est prioritaire sur le niveau, tu as juste a inversé les clés dans la fonction cmp)


Message édité par anapajari le 18-07-2006 à 11:58:13
Reply

Marsh Posté le 18-07-2006 à 13:05:49    

Oui ton exemple fonctionne mais il est très simple.
Si tu construits ce tableau :

Code :
  1. $arr = array(
  2. array( 'niveau' => 0, 'lot_pere' => 'A'),
  3. array( 'niveau' => 0, 'lot_pere' => 'B'),
  4. array( 'niveau' => 1, 'lot_pere' => 'A'),
  5. array( 'niveau' => 1, 'lot_pere' => 'B'),
  6. array( 'niveau' => 2, 'lot_pere' => 'A'),
  7. array( 'niveau' => 3, 'lot_pere' => 'A'),
  8. );


Tu as comme résultat :

Code :
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [niveau] => 0
  6.             [lot_pere] => A
  7.         )
  8.     [1] => Array
  9.         (
  10.             [niveau] => 0
  11.             [lot_pere] => B
  12.         )
  13.     [2] => Array
  14.         (
  15.             [niveau] => 1
  16.             [lot_pere] => A
  17.         )
  18.     [3] => Array
  19.         (
  20.             [niveau] => 1
  21.             [lot_pere] => B
  22.         )
  23.     [4] => Array
  24.         (
  25.             [niveau] => 2
  26.             [lot_pere] => A
  27.         )
  28.     [5] => Array
  29.         (
  30.             [niveau] => 3
  31.             [lot_pere] => A
  32.         )
  33. )


 
Or je voudrai :

Code :
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [niveau] => 0
  6.             [lot_pere] => A
  7.         )
  8.     [1] => Array
  9.         (
  10.             [niveau] => 1
  11.             [lot_pere] => A
  12.         )
  13.     [2] => Array
  14.         (
  15.             [niveau] => 2
  16.             [lot_pere] => A
  17.         )
  18.     [3] => Array
  19.         (
  20.             [niveau] => 3
  21.             [lot_pere] => A
  22.         )
  23.     [4] => Array
  24.         (
  25.             [niveau] => 0
  26.             [lot_pere] => B
  27.         )
  28.     [5] => Array
  29.         (
  30.             [niveau] => 1
  31.             [lot_pere] => B
  32.         )
  33. )


 
Note : la construction du tableau se fera toujours pareils, j'empile les niveaux au fur et à mesure.


Message édité par NerOcrO le 18-07-2006 à 13:06:12
Reply

Marsh Posté le 18-07-2006 à 13:05:49   

Reply

Marsh Posté le 18-07-2006 à 13:14:56    

J'ai presque quelque chose avec ceci :

Code :
  1. function compare($a, $b) {
  2. if($a['niveau'] == $b['niveau'])
  3.  return 0;
  4. else {
  5.  if($a['lot_pere'] == $b['lot_pere']) {
  6.   return ($a['niveau'] > $b['niveau']) ? -1 : 1;
  7.  } else {
  8.   return ($a['niveau'] < $b['niveau']) ? -1 : 1;
  9.  }
  10. }

Reply

Marsh Posté le 18-07-2006 à 13:22:28    

c'est dans le mauvais sens, je t'avais dit d'inverser les clés dans ma fonction du dessus. J'avais mis en 1 niveau et en 2 lot_pere, toi tu veux le contraire:

Code :
  1. function cmp($a, $b){
  2.   if ( $a['lot_pere'] == $b['lot_pere']){
  3.     if ( $a['niveau'] == $b['niveau']){
  4.       return 0;
  5.     } else {
  6.        return ($a['niveau'] < $b['niveau']) ? -1 : 1;
  7.      }
  8.    } else {
  9.      return ($a['lot_pere'] < $b['lot_pere']) ? -1 : 1;
  10.    }
  11. }


Message édité par anapajari le 18-07-2006 à 13:23:27
Reply

Marsh Posté le 18-07-2006 à 14:08:38    

Comment je te respectes mon ami :D
 
Merci à toi !!!
 
Pourrais tu m'expliquer en quelques lignes comment fonctionne ta fonction, le principe car le coup des return 0, 1 ou -1, je capte pas des masses.

Reply

Marsh Posté le 18-07-2006 à 14:20:55    

Bon en fait, j'ai oublié une donnée importante :( (quel boulet).
Mon tableau devait ressembler plus à ceci :

Code :
  1. $array_trc = array(
  2. array('num_lot' => "635E16124614", 'niveau' => 0, 'lot_pere' => "635E16124614" ),
  3. array('num_lot' => "635E16124615", 'niveau' => 0, 'lot_pere' => "635E16124615" ),
  4. array('num_lot' => "635E16124616", 'niveau' => 1, 'lot_pere' => "635E16124615" ),
  5. array('num_lot' => "635E16124617", 'niveau' => 1, 'lot_pere' => "635E16124614" ),
  6. array('num_lot' => "635E16124618", 'niveau' => 2, 'lot_pere' => "635E16124616" ),
  7. array('num_lot' => "635E16124619", 'niveau' => 2, 'lot_pere' => "635E16124617" ),
  8. array('num_lot' => "635E16124620", 'niveau' => 3, 'lot_pere' => "635E16124618" ),
  9. array('num_lot' => "635E16124621", 'niveau' => 3, 'lot_pere' => "635E16124619" ),
  10. );


 
Oui car derrière, je fais une arborescence type treeview.
Désolé, ça complique la chose :s

Reply

Marsh Posté le 18-07-2006 à 14:26:42    

bin en fait je vois pas trop ou c'est pas clair :/  
En gros tu compares 2 choses A et B selon deux critères, qui sont dans l'ordre d'importance lot_pere et niveau.
La fonction retourne -1 si A est plus petit que B, 0 si les deux sont égaux, 1 si A est plus grand que B.
Donc ça fait:


* SI "lot_pere A" est égal à "lot_pere B"
 - SI "niveau A" est égal à "niveau B"
   + A et B sont égaux
 - SINON
   + SI "niveau A" est inférieur à "niveau B", A est plus petit que B
   + SI "niveau A" est supérieur à "niveau B", A est plus grand que B
* SINON
  - SI "lot_pere A" est inférieur à "lot_pere B", A est plus petit que B
  - SI "lot_pere A" est supérieur à "lot_pere B", A est plus grand que B


ça va comme ça?
 
edit:
Quand a ton dernier post, tu es en train de dire qu'il y a une troisième "critère" qui intervient?
Inspire toi de ce qui est au dessus, pour le rajouter. C'est pas très compliqué


Message édité par anapajari le 18-07-2006 à 14:28:16
Reply

Marsh Posté le 18-07-2006 à 15:31:41    

Ouais mais je ne vois pas trop où mettre ma condition avec num_lot :s

Reply

Marsh Posté le 18-07-2006 à 15:44:23    

à la place de  

+ A et B sont égaux

Reply

Marsh Posté le 18-07-2006 à 15:58:08    

Oui c'est ce que j'ai pensé tout de suite mais ça ne sert à rien, j'ai remarqué qu'avec le nouveau tableau, il passe pratiquement dans * SINON car c'est impossible qu'il y ai des doublons.
J'commence à m'épuiser mentalement lol.


Message édité par NerOcrO le 18-07-2006 à 16:00:42
Reply

Marsh Posté le 18-07-2006 à 16:01:39    

bon montre la fonction que tu as écrite avec le dernier critère...

Reply

Marsh Posté le 18-07-2006 à 16:18:16    

J'ai simplement fait ça pour l'instant :

Code :
  1. function cmp($a, $b){
  2.        if ( $a['num_lot'] == $b['lot_pere']){
  3.          if ( $a['niveau'] == $b['niveau']){
  4.            return 0;
  5.          } else {
  6.             return ($a['niveau'] < $b['niveau']) ? -1 : 1;
  7.           }
  8.         } else {
  9.           return ($a['lot_pere'] < $b['lot_pere']) ? -1 : 1;
  10.         }
  11.       }


 
Ca fonctionne quand j'ai deux niveaux mais à partir de 3, les autres niveaux sont tout le temps mis à lafin du tableau.
Là je met des echo un peu partout pour débugguer.

Reply

Marsh Posté le 18-07-2006 à 16:40:53    

Sinon tu joues du Banjo le dimanche? Nan parce que le l'informatique ça me semble pas être ton truc ( sans méchanceté) :o
 
Alors deux solutions:

  • soit tu souhaites trier ton tableau selon les trois critères num_lot, lot_pere, niveau ( ici présentés dans l'ordre d'importance)

Sur l'exemple suivant tu chercherais donc à transformer:


NL|LP|NV
 4| 3| 1
 4| 2| 2
 4| 2| 1
 1| 4| 3


en


NL|LP|NV
 1| 4| 3
 4| 2| 1
 4| 2| 2
 4| 3| 1


auquel cas, tu dois vraiment t'en sortir tout seul ( tu as juste a copier un bout déjà fait, changer les clés et le colé à la place de la ligne marquée plus haut
 

  • Soit tu souhaites trier selon un autre ordre, genre tu veux un num lot, puis toutes lignes qui ont un lot_pere égale à ce num_lot ... Et là tu oublies tout de suite, tu t'en sortiras pas en faisant un tri!

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed