Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/09/2008, 00h20   #1
Invité de passage
 
Inscription : septembre 2008
Messages : 19
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 19
Points : 3
Points : 3
Par défaut [Tableaux] tri tableaux multidimensionnels

Une requete mysql me retourne des enregistrements triés sur le champ pagetitle.

La structure retournée contient les champs id et pagetitle et type :

Code :
1
2
3
4
5
6
7
8
$data[] = array( 'id' => 63 ,'title' => p8 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 66 ,'title' => p7 , 'type' => 0, 'rank' => 101 );
$data[] = array( 'id' => 69 ,'title' => p6 , 'type' => 1, 'rank' => 1 );
$data[] = array( 'id' => 71 ,'title' => p5 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 72 ,'title' => p4 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 67 ,'title' => p3 , 'type' => 1, 'rank' => 1 );
$data[] = array( 'id' => 70 ,'title' => p2 , 'type' => 1, 'rank' => 101);
$data[] = array( 'id' => 64 ,'title' => p1 , 'type' => 1, 'rank' => 1 );
A cette structure je rajoute une colonne "rank" et je souhaite trier tous les lignes sur la base de cette colonne, tout en conservant l'ordre relatif des autres colonnes (puisque déjà trié).

Pour cela j'utilise la fonction array_multisort:
Code :
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
 
<?php
$data[] = array( 'id' => 63 ,'title' => p8 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 66 ,'title' => p7 , 'type' => 0, 'rank' => 101 );
$data[] = array( 'id' => 69 ,'title' => p6 , 'type' => 1, 'rank' => 1 );
$data[] = array( 'id' => 71 ,'title' => p5 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 72 ,'title' => p4 , 'type' => 0, 'rank' => 1 );
$data[] = array( 'id' => 67 ,'title' => p3 , 'type' => 1, 'rank' => 1 );
$data[] = array( 'id' => 70 ,'title' => p2 , 'type' => 1, 'rank' => 101);
$data[] = array( 'id' => 64 ,'title' => p1 , 'type' => 1, 'rank' => 1 );
 
for($d=0;$d<count($data);$d++) {
  print_r($data[$d]);
  echo "<br />\n\r";
}
 
echo "<br />\n\r";
 
foreach ($data as $key => $row) {
   $rank[$key]  = $row['rank'];
}
 
array_multisort($rank, SORT_DESC, $data);
 
for($d=0;$d<count($data);$d++) {
  print_r($data[$d]);
  echo "<br />\n\r";
}
?>
Seul problème, si la colonne rank est bien triée, l'ordre initial de la colonne pagetitle est lui modifié. En fait la fonction utilise la colonne id pour trier les lignes de même valeur rank par valeur ASC. Résultat le tri sur la colonne pagetitle est perdu.
Cf exemple ci-dessus à faire tourner.

Comment puis je trier les lignes du tableau en me basant sur la valeur rank sans perdre l'ordre des colonnes suivantes ?

Dit autrement on obtient cela, a savoir les lignes de rank=1 triées sur le champ ID:
Code :
1
2
3
4
5
6
7
8
9
 
Array ( [id] => 66 [title] => p7 [type] => 0 [rank] => 101 )
Array ( [id] => 70 [title] => p2 [type] => 1 [rank] => 101 )
Array ( [id] => 63 [title] => p8 [type] => 0 [rank] => 1 )
Array ( [id] => 64 [title] => p1 [type] => 1 [rank] => 1 )
Array ( [id] => 67 [title] => p3 [type] => 1 [rank] => 1 )
Array ( [id] => 69 [title] => p6 [type] => 1 [rank] => 1 )
Array ( [id] => 71 [title] => p5 [type] => 0 [rank] => 1 )
Array ( [id] => 72 [title] => p4 [type] => 0 [rank] => 1 )
et je voudrais avoir cela, c.a.d conserver le tri initial sur pagetitle
Code :
1
2
3
4
5
6
7
8
9
 
Array ( [id] => 66 [title] => p7 [type] => 0 [rank] => 101 )
Array ( [id] => 70 [title] => p2 [type] => 1 [rank] => 101 )
Array ( [id] => 66 [title] => p8 [type] => 0 [rank] => 1 )
Array ( [id] => 69 [title] => p6 [type] => 1 [rank] => 1 )
Array ( [id] => 71 [title] => p5 [type] => 0 [rank] => 1 )
Array ( [id] => 72 [title] => p4 [type] => 0 [rank] => 1 )
Array ( [id] => 67 [title] => p3 [type] => 1 [rank] => 1 )
Array ( [id] => 64 [title] => p1 [type] => 1 [rank] => 1 )
Je précise que dans l'exemple j'utilise pagetitle mais je pourrais avoir un nombre variables de colonnes déjà triées, donc impossible d'utiliser la colonne pagetitle pour préciser l'ordre en plus de celui de rank.

Merci de votre aide
cariboo45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/09/2008, 11h43   #2
Expert Confirmé Sénior
 
Avatar de Mr N.
 
Inscription : septembre 2004
Messages : 5 421
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 421
Points : 5 835
Points : 5 835
Bienvenue sur les forums de developpez.com

Ta colonne rank, tu l'ajoute comment ?
Sur la base de quel critère ?
Tu peux pas l'ajouter lors de ta requete SQL, ce qui te permettra de faire le tri avec MySQL ?
__________________
Get your motor runnin'
Head out on the highway...
Mr N. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/09/2008, 19h58   #3
Invité de passage
 
Inscription : septembre 2008
Messages : 19
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 19
Points : 3
Points : 3
Citation:
Ta colonne rank, tu l'ajoute comment ?
Je l'ajoute après la requete SQL car j'ai besoin du résultat (lecture d'un champ de type text et recherche du nombre de mots) pour calculer la valeur de rank. J'ajoute la valeur de rank à la structure retournée par Mysql. Je ne peux donc pas utiliser mysql pour trier aussi la colonne rank.
cariboo45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2008, 12h31   #4
Expert Confirmé Sénior
 
Avatar de Mr N.
 
Inscription : septembre 2004
Messages : 5 421
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 421
Points : 5 835
Points : 5 835
Ok, alors il faut gruger.

Tu as ton ordre qui bon. Donc tu rajoutes une colonne virtuelle de tri sur laquelle se basera array_multisort.
Cette colonne contient simplement le numéro d'ordre actuel.

ça revient à faire en sql: GROUP BY rank DESC, <rank_precedent> ASC

Code :
1
2
3
4
5
6
7
$i = 0;
foreach ($data as $key => $row) {
   $rank[$key]  = $row['rank'];
   $rank_2[$key] = $i++; //equivalent à $key
}
 
array_multisort($rank, SORT_DESC, $rank_2, SORT_ASC, $data);
__________________
Get your motor runnin'
Head out on the highway...
Mr N. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2008, 17h06   #5
Invité de passage
 
Inscription : septembre 2008
Messages : 19
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 19
Points : 3
Points : 3
Waouh!. Solution élégante. Le nez sur le problème je ne voyais même plus la solution. Merci pour ton aide précieuse.
cariboo45 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h55.


 
 
 
 
Partenaires

Hébergement Web