IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Tableaux] Tri tableau multidimensionnel en fonction d'une de ses colonnes


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 47
    Points
    47
    Par défaut [Tableaux] Tri tableau multidimensionnel en fonction d'une de ses colonnes
    Bonjour, j'espère que quelqu'un pourra m'aider car je suis désespéré...

    Voila j'explique le probleme: je voudrai réaliser le tri d'un tableau multidimensionnel en fonction d'une colonne de ce dernier. J'ai essayé en vain avec les fonctions php, notamment multisort_array, mais je ne parviens a ne trier que la colonne en question et non tout le tableau, ou alors j'ai du mal utiliser la fonction....

    voici mon tableau , chaque colonne contient une liste de valeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Array ( [id] => Array ( [0] => 66656 [1] => 38607 [2] => 41478 [3] => 68722 ) [submitter] => Array ( [0] => villeruptimmo_athomelor [1] => unicorn_athome [2] => dfiest_athome [3] => dargent_athomelor ) [offerstate] => Array ( [0] => active [1] => active [2] => active [3] => active ) [insdate] => Array ( [0] => 2005-05-12 10:28:40 [1] => 2005-06-08 09:07:20 [2] => 2005-07-21 18:20:25 [3] => 2005-09-14 15:30:59 ) [numChamb] => Array ( [0] => 6 [1] => 3 [2] => 8 [3] => 4 ) [country] => Array ( [0] => France [1] => France [2] => France [3] => France ) [region] => Array ( [0] => Meurthe et Moselle [1] => Moselle [2] => Moselle [3] => Meurthe et Moselle ) [immotype] => Array ( [0] => 13 [1] => 13 [2] => 18 [3] => 1 ) [commune] => Array ( [0] => Villerupt [1] => Rettel [2] => METRICH [3] => Longwy ) [garage] => Array ( [0] => -1 [1] => 1 [2] => 1 [3] => -1 ) [prix] => Array ( [0] => 220000 [1] => 195000 [2] => 466000 [3] => 345000 ) [surface] => Array ( [0] => 0.00 [1] => 140.00 [2] => 354.00 [3] => 350.00 ) )

    Moi par exemple ce que je voudrai c'est par exemple trier chaque ligne en fonction par exemple des ID croissants. J'ai alors tenté:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    array_multisort($tableModifie['id'], SORT_ASC , SORT_NUMERIC);
    Mai ca ne trie que la colonne tri et les autres n'ont pas été modifiées...

    Sinon quelqu'un aurait il une autre idée afin de trier un tel tableau sachant que j'ai besoin du tri et de l'ordre...

    je vous remercie d'avance

  2. #2
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    Il faut lui donner toutes les colonnes que tu souhaites trier... donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?php
    $aTab = array ('id' => array ('0' => '66656' ,'1' => '38607' ,'2' => '41478' ,'3' => '68722' ),'submitter' => array ('0' => 'villeruptimmo_athomelor' ,'1' => 'unicorn_athome' ,'2' => 'dfiest_athome' ,'3' => 'dargent_athomelor' ),'offerstate' => array ('0' => 'active' ,'1' => 'active' ,'2' => 'active' ,'3' => 'active' ),'insdate' => array ('0' => '2005-05-12 10:28:40' ,'1' => '2005-06-08 09:07:20' ,'2' => '2005-07-21 18:20:25' ,'3' => '2005-09-14 15:30:59' ),'numChamb' => array ('0' => '6' ,'1' => '3' ,'2' => '8' ,'3' => '4' ),'country' => array ('0' => 'France' ,'1' => 'France' ,'2' => 'France' ,'3' => 'France' ),'region' => array ('0' => 'Meurthe et Moselle' ,'1' => 'Moselle' ,'2' => 'Moselle' ,'3' => 'Meurthe et Moselle' ),'immotype' => array ('0' => '13' ,'1' => '13' ,'2' => '18' ,'3' => '1' ),'commune' => array ('0' => 'Villerupt' ,'1' => 'Rettel' ,'2' => 'METRICH' ,'3' => 'Longwy' ),'garage' => array ('0' => '-1' ,'1' => '1' ,'2' => '1' ,'3' => '-1' ),'prix' => array ('0' => '220000' ,'1' => '195000' ,'2' => '466000' ,'3' => '345000' ),'surface' => array ('0' => '0.00' ,'1' => '140.00' ,'2' => '354.00' ,'3' => '350.00' ));
     
    echo '<pre>';
    print_r($aTab);
     
    array_multisort(	$aTab['id'], SORT_ASC , SORT_NUMERIC,
    					$aTab['submitter']
    					$aTab['offerstate'],
    					$aTab['insdate'] ,
    					$aTab['numChamb'] ,
    					$aTab['country'], 
    					$aTab['region'] ,
    					$aTab['immotype'] ,
    					$aTab['commune'] ,
    					$aTab['garage'] ,
    					$aTab['prix'],
    					$aTab['surface']
    );
     
    echo '<hr><pre>';
    print_r($aTab);
     
    ?>

  3. #3
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 47
    Points
    47
    Par défaut AIDE 2
    Merci beaucoup pour votre réponse, j'ai esssayé et ca marche bien, mais j'ai un autre soucis, et j'ai tenté de le résoudre en vain aussi.....

    Vous l'avez surement compris, la méthode de tri est appelé pour trier le tableau lorsque l'on a sélectionné un tri et/ou un ordre. par contre il faut que je fasse ce tri sur la colonne en question (faire un test) et lister toutes les autres colonnes dans les paramétrés de la fonction. Je vois pas comment faire car c'est dynamique. Je pensais faire une variable qui contiendrais tous les tableaux des autres colonnes de cette manière:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    // Test sur l'ordre sélectionné
    if($_POST['param_ordre']=="ASC")
    {
    	$ordre=SORT_ASC;
    }else if($this->view->param_ordre=="DESC")
    {	
    	$ordre=SORT_DESC;		
    }		
     
    // Test sur le tri sélectionné
    if($_POST['param_tri']=="ASC")
    {
    	$tri='id';
    }
     
    // selection de toutes les colonnes autres que celle concernée par le tri
    $lestableau=$tableModifie['submitter'].",".
    $tableModifie['offerstate'].",".
    $tableModifie['insdate'].",".
    $tableModifie['numChamb'].",".
    $tableModifie['country'].",". 
    $tableModifie['region'].",".
    $tableModifie['immotype'].",".
    $tableModifie['commune'].",".
    $tableModifie['garage'].",".
    $tableModifie['prix'].",".
    $tableModifie['surface'];
     
    array_multisort($tableModifie[$tri], $ordre , SORT_NUMERIC,
    					$lestableau
    );
    Mais quand je lance ceci ca me dit que les 4eme paramètre n'est pas un tableau

  4. #4
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    ok.
    En effet, comme ca, ca ne peux pas marcher.

    Le mieux je pense est de gérer la liste des colonnes dans un autre tableau ;o)

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $tri=$_POST['colonneTri'];
     
    $listeColonnes=array('id', 'prix', 'surface', 'region',...); // 12 elements
     
    unset($listeColonnes[array_search($listeColonnes[$tri])]); // on "supprime" la colonne correspondant au tri
    // une autre solution :
    // $listeColonnes=array_flip($listeColonnes);
    // unset($listeColonnes[$tri]);
    // $listeColonnes=array_flip($listeColonnes);
     
    array_multisort(
      $tab[$tri], ..., ..., // on va trier selon la colonne du tri
      $tab[$listeColonnes[0]], // on ajoute toutes les autres colonnes
      $tab[$listeColonnes[1]],
      $tab[$listeColonnes[2]],
      $tab[$listeColonnes[3]],
    ...
      $tab[$listeColonnes[9]],
      $tab[$listeColonnes[10]] // on va jusqu'a l'index 10 car la liste commence a 0, et on a enlevé un element, donc on a bien 11 elements en tout + la colonne de tri
    );
    Il y aurait d'autres methodes basées sur eval, qui permet d'executer le code php écrit dans une chaine construite grace a des concaténations comme tu le fait, mais c'est beaucoup moins propre ;o)

  5. #5
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 47
    Points
    47
    Par défaut
    Merci encore pour votre réponse, que je viens de tester,
    j'ai une erreur cependant au niveau de la fonction de suppression de la colonne du tri :

    j'obtiens les erreurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Notice: Undefined index: id  
     
    // ET
     
    Wrong parameter count for array_search()
    J'ai d'ailleurs tester directement dans la fonction sans récupérer le _POST en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unset($listeColonnes[array_search($listeColonnes['id'])])
    mais sans succès.

    J'ai trouvé la solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unset($listeColonnes[array_search($tri,$listeColonnes)]); // on "supprime" la colonne correspondant au tri
    Par contre en faisant un print_r() du nouveau tableau je me suis rendu compte que le la suppression de la colonne du tri, entraine la suppression de l'indice et le tableau possède alors un trou..esty il possible de redéfinir le tableau pour qu'il n'y ait plus ce "trou";

  6. #6
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    oui, en effet, j'ai écrit n'importe quoi dans array_search ;o)

    Pour éviter le "trou", on peut faire ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $listeColonnes = array_values($listeColonnes);
    ca va réindexer les elements.

  7. #7
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 102
    Points : 47
    Points
    47
    Par défaut AIDE FINALE
    Voila c'est bon j'ai réussi à faire ce que je voulais, merci beaucoup.

    Je voudrais pour terminer vous poser une question car vous m'avez l'air d'être quelqu'un qui connait très bien le php.

    Alors voila je vous explique : le tableau crée précédemment est utilisé pour lister un contenu volumineux provenant d'une bdd elle aussi volumineuse (plus de 190 tables). Ne désirant pas surcharger MYSQL et le serveur, j'ai désiré faire la requête 1 seule fois: je mets alors les résultats de cette dernière dans un tableau (le fameux tableau initial :-) ). Puis je le mets en cache.

    Si je sélectionne un tri particulier et/ou un ordre je récupère le cache et je fais le tri établi précédemment. tout fonctionne c super....

    Mais je voudrais faire un système de pagination...alors voila la question et je voudrais avoir votre avis: qu'est il préférable de faire afin de réduire la consommation des ressources au niveau MYSQL et du serveur, et ainsi de réduire le temps de traitement??

    1) mettre en cache (dans le tableau initial) tous les résultats (pouvant comptabiliser des milliers de lignes), puis rappeler les résultats (de 10 en 10 par exemple) dans chaque page, et remettre en cache pour un tri éventuel.

    ou

    2) refaire la requête initiale a chaque foi que l'on change de page (avec la clause LIMIT), puis mettre en cache les résultats.

    Par la même occasion, le choix du tri et de l'ordre doit il, à votre avis, se faire sur tous les résultats, ou simplement sur ceux de la page en cours??

    Merci beaucoup pour votre aide

  8. #8
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    Bon... quelques points deja :

    * Un tri MYSQL sera toujours plus rapide qu'un tri PHP
    * PHP est un langage "stateless", donc une fois que la page est chargée, les objets sont détruits... donc pour implementer une notion de "cache" en PHP il faudrait stocker l'infos dans une session... qui a une taille limitée ! Ou dans un fichier... mais le temps d'écriture et d'acces a un fichier n'est pas tres éloigné d'une execution de requete si celle ci est sans jointure et avec une clause where simple.
    * Pour le tri global puis pagination ou pour la pagination puis le tri, c'est a voir avec l'utilisateur... en principe il prefere le tri global puis la pagination.

    Petite remarque au passage : LIMIT de mysql n'est pas ultra performant hélas ;o) mais il n'y a pas grand chose de mieux pour faire ca.

    Vous avez donc 2 possibilités :
    A) Récuperer toutes les données en UNE seule fois et les afficher sur la page du navigateur client... ca va etre TRES long (en esperant ne pas depasser le timeout) mais ensuite la pagination et le tri peuvent etre fait... en javascript ! Donc aucune charge serveur.
    B) Récuperer les données d'une page avec LIMIT, eventuellement avec un ORDER BY en MYSQL qui vient de l'utilisateur.
    Sur la page affichée, le tableau pourra etre retrié "localement" en javascript, sans requete SQL. Par contre, lors de l'affichage de la 2eme page, le tri doit s'effectuer sur la meme colonne que lors de la 1ere requete (sinon on aura des résultats incohérents) a moins que l'utilisateur ait spécifié un autre tri explicitement.

    J'avoue que je préfère la 2eme methode. Cela suppose avoir 2 criteres de tri : 1 pour la requete sql et 1 autre pour le javascript.
    Pour faire ca, le mieux serait d'avoir :
    * Un <select> du genre "Trier par : [.....]" => Requete SQL / Rechargement de page
    * des fleches "triangle haut/triangle bas" sur les entetes de chaque colonne du tableau pour retrier au sein de la meme page en javascript.

    Si vous ne souhaitez pas implementer du javascript, la pagination avec mysql reste le meilleur moyen, et un 2eme tri en php pour éviter de faire la requete (sur la meme page)... pourquoi pas !

    PS : En fait c'est quoi que vous utilisez comme "cache" ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Tri tableau HTML en fonction d'une colonne et ses valeurs.
    Par hugerma dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 10/12/2014, 08h04
  2. Réponses: 5
    Dernier message: 04/02/2014, 10h52
  3. [Tableaux] tri tableau avec fonction
    Par ascito dans le forum Langage
    Réponses: 7
    Dernier message: 10/09/2008, 14h21
  4. Réponses: 2
    Dernier message: 15/05/2007, 16h56
  5. [Tableaux] Tri tableau
    Par licorne dans le forum Langage
    Réponses: 3
    Dernier message: 20/03/2006, 12h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo