Inversion et tri tableau multidimentionnel

a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006 - 7 nov. 2006 à 10:24
a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006 - 10 nov. 2006 à 09:13
Bonjour,

J'ai un tableau multidimentionnel de la forme

$tab = Array
(
[0] =>

Array
(


[0] => Array
(
[ID_CL] => 1232
[ID_PC] => 1857
[code] => XE206
[libelle] => legume
[famille] => ENDIVE
[ordre] => 0
)

 [1] => Array
(
[ID_CL] => 1232
[ID_PC] => 2090
[code] => XEFP510MIX
[libelle] => legume
[famille] => ENDIVE[ordre] => 1
)

 [2] => Array
(
[ID_CL] => 1232
[ID_PC] => 1864
[code] => EFP1KGA
[libelle] => fruits
[famille] => fraise 
[ordre] => 2
)

 [3] => Array
(
[ID_CL] => 1232
[ID_PC] => 1868
[code] => EFP500NT
[libelle] => divers[famille] => soupe 
[ordre] => 3
))
[1] =>Array
(



[0] => Array
(
[ID_CL] => 1240
[ID_PC] => 1857
[code] => XE206
[libelle] => legume
[famille] => ENDIVE
[ordre] => 0
)


 [1] => Array
(
[ID_CL] => 1240
[ID_PC] => 2090
[code] => XEFP510MIX
[libelle] => legume
[famille] => ENDIVE[ordre] => 1
)


 [2] => Array
(
[ID_CL] => 1240
[ID_PC] => 1864
[code] => EFP1KGA
[libelle] => fruits
[famille] => fraise 
[ordre] => 2
)


 [3] => Array
(
[ID_CL] => 1240
[ID_PC] => 1868
[code] => EFP500NT
[libelle] => divers[famille] => soupe 
[ordre] => 3
)).


Je voudrais intervertir 2 lignes pour donner:

$tab = Array
(
[0] =>


Array
(



[0] => Array
(
[ID_CL] => 1232
[ID_PC] => 1857
[code] => XE206
[libelle] => legume
[famille] => ENDIVE
[ordre] => 0
)

 [1] => Array
(
[ID_CL] => 1232
[ID_PC] => 1864
[code] => EFP1KGA
[libelle] => fruits
[famille] => fraise 
[ordre] => 2
)


 [2] => Array
(
[ID_CL] => 1232
[ID_PC] => 2090
[code] => XEFP510MIX
[libelle] => legume
[famille] => ENDIVE[ordre] => 1
)


 [3] => Array
(
[ID_CL] => 1232
[ID_PC] => 1868
[code] => EFP500NT
[libelle] => divers[famille] => soupe 
[ordre] => 3
))

[1] =>Array
(




[0] => Array
(
[ID_CL] => 1240
[ID_PC] => 1857
[code] => XE206
[libelle] => legume
[famille] => ENDIVE
[ordre] => 0
)



  [1] => Array
(
[ID_CL] => 1240
[ID_PC] => 1864
[code] => EFP1KGA
[libelle] => fruits
[famille] => fraise 
[ordre] => 2
)


 [2] => Array
(
[ID_CL] => 1240
[ID_PC] => 2090
[code] => XEFP510MIX
[libelle] => legume
[famille] => ENDIVE[ordre] => 1
)



 [3] => Array
(
[ID_CL] => 1240
[ID_PC] => 1868
[code] => EFP500NT
[libelle] => divers[famille] => soupe 
[ordre] => 3
)).


De plus je voudrais faire des tris sur n'importe qu'elle valeur (ex libellé ou ordre), croissant ou décroissant.

Merci de m'apporter vos lumières...

10 réponses

cs_alexscott Messages postés 54 Date d'inscription vendredi 28 février 2003 Statut Membre Dernière intervention 10 novembre 2006
7 nov. 2006 à 14:09
ben pour les tris regardent sur php.net ce qui existe : sort, usort, asort, array_multisort, ... tu trouveras forcement ton bonheur. (http://fr.php.net/manual/fr/ref.array.php)
quand tu dis intervertir des lignes tu veux dire intervertir leur index je pense tu peux le faire betement en sauvant ce que tu as en [1] dans une var annexe puis tu mets [2] dans [1] et tu mets ce que tu as sauve dans [2] ou tu peux faire joujou avec usort ou array_multisort enfin rien de vraiment excpetionnel si ce n'est de lire la doc :D
0
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
8 nov. 2006 à 15:17
Salut,

t'as un sort avec un callback, ça peut se faire facilement à partire de ça, j'ai pas la doc en tête, ni mes sources sous la main, mais je l'avais utilisé pour trier les noms des connectés sur IRC en fonction de l'ordre alphabetique et de leur status

In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy

Mon site (articles sur la programmation et programmes)
0
cs_alexscott Messages postés 54 Date d'inscription vendredi 28 février 2003 Statut Membre Dernière intervention 10 novembre 2006
8 nov. 2006 à 18:30
c'est le usort je le cite pas pour rien :)
0
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
8 nov. 2006 à 20:18
Salut,

* : Mon site (articles sur la programmation et programmes)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006
9 nov. 2006 à 10:08
Merci mais je n'ai pas l'impression que ca marche avec un tableau à 3 dimensions.
0
a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006
9 nov. 2006 à 10:08
Merci mais je n'ai pas l'impression que ca marche avec un tableau à 3 dimensions.
0
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
9 nov. 2006 à 11:40
Salut,

ça va te trier les éléments du premier en appellant une fonction de callback...

c'est simple comme truc, mais faut t'en donner la peine... sinon, tu peux bosser les algos de tris, t'as des descriptions détaillées sur wikipedia...

In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy

Mon site (articles sur la programmation et programmes)
0
a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006
9 nov. 2006 à 12:19
Désolé mais qu'est ce que tu appelles une fonction de callback?
0
cs_alexscott Messages postés 54 Date d'inscription vendredi 28 février 2003 Statut Membre Dernière intervention 10 novembre 2006
10 nov. 2006 à 04:57
<?
//fonction de callback pour un tri a 1 cle
function mytri($a, $b)
{
global $mytritype;

if ($a[$mytritype] == $b[$mytritype])
return(0);

return(($a[$mytritype] > $b[$mytritype]) ? 1 : -1);
}

//fonction de callback pour un tri a 2 cles
function mytri2($a, $b)
{
global $mytritype1;
global $mytritype2;

if ($a[$mytritype1] == $b[$mytritype1])
{
if ($a[$mytritype2] == $b[$mytritype2])
return(0);

return(($a[$mytritype2] > $b[$mytritype2]) ? 1 : -1);
}

return(($a[$mytritype1] > $b[$mytritype1]) ? 1 : -1);
}

//met l'element qui etait a la place $ord a la place $val et decale les autres elements
function echange($tab, $ord, $val)
{
if ($val < $ord)
{
for($i = 0; $i < count($tab); $i++)
{
if(($tab[$i]['ordre'] >= $val) && ($tab[$i]['ordre'] < $ord))
$tab[$i]['ordre'] += 1;
}
}
elseif ($val > $ord)
{
for($i = 0; $i < count($tab); $i++)
{
if(($tab[$i]['ordre'] <= $val) && ($tab[$i]['ordre'] > $ord))
$tab[$i]['ordre'] -= 1;
}
}

$tab[$ord]['ordre'] = $val;

return($tab);
}

#MAIN
global $mytritype;
global $mytritype1;
global $mytritype2;

$tab = array(
array(
array( 'ID_CL' => 1232, 'ID_PC' => 1857, 'code' => 'XE206', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 0 ),
array( 'ID_CL' => 1232, 'ID_PC' => 2090, 'code' => 'XEFP510MIX', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 1 ),
array( 'ID_CL' => 1232, 'ID_PC' => 1864, 'code' => 'EFP1KGA', 'libelle' => 'fruits', 'famille' => 'fraise', 'ordre' => 2 ),
array( 'ID_CL' => 1232, 'ID_PC' => 1868, 'code' => 'EFP500NT', 'libelle' => 'divers', 'famille' => 'soupe', 'ordre' => 3 )
),
array(
array( 'ID_CL' => 1240, 'ID_PC' => 1857, 'code' => 'XE206', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 0 ),
array( 'ID_CL' => 1240, 'ID_PC' => 2090, 'code' => 'XEFP510MIX', 'libelle' => 'legume', 'famille' => 'ENDIVE', 'ordre' => 1 ),
array( 'ID_CL' => 1240, 'ID_PC' => 1864, 'code' => 'EFP1KGA', 'libelle' => 'fruits', 'famille' => 'fraise', 'ordre' => 2 ),
array( 'ID_CL' => 1240, 'ID_PC' => 1868, 'code' => 'EFP500NT', 'libelle' => 'divers', 'famille' => 'soupe', 'ordre' => 3 )
)
);

print_r($tab);

//dans une boucle si on part du principe qu'on fait le meme changement d'ordre pour tous les sous-tableaux
foreach($tab as &$val)
$val = echange(&$val, 0, 2);
//print_r($tab);

//ensuite on souhaite retrier les tableaux en fonction de l'ordre
$mytritype = 'ordre';
foreach($tab as &$val)
usort(&$val, 'mytri');
//print_r($tab);

//ensuite on souhaite retrier les tableaux en fonction de l'ID_PC
$mytritype = 'ID_PC';
foreach($tab as &$val)
usort(&$val, 'mytri');
//print_r($tab);

//evidemment si ton but et de "perdre une dimension il suffit de faire"
$newtab = array();
foreach($tab as &$val)
$newtab = array_merge($newtab, $val);
print_r($newtab);

$mytritype = 'ID_PC';
usort($newtab, 'mytri');
print_r($newtab);

//Ha et que tu perdes ou non une dimension si tu veux faire un tri a plusieurs cles
//je le fais pour 2 car pour 3 c'est pareil en plus complique
//ca vaut peut-etre le coup d'utiliser array_multisort d'ailleurs dans ce cas la
//enfin c'est chiant array_multisort je te ferais une demo pour trier avec les deux
//memes cles juste apres

$mytritype1 = 'ordre';
$mytritype2 = 'ID_CL';
usort($newtab, 'mytri2');
print_r($newtab);

//alors pour faire ce dernier tri que je viens de faire avec array_multisort
//il faut extraire les colonnes qui nous interessent
//je fais des SORT_DESC pour qu'on puisse observer le fait que le tri a ete effectue
$key1 = array();
$key2 = array();

foreach($newtab as $val)
{
$key1[] = $val[$mytritype1];
$key2[] = $val[$mytritype2];
}

array_multisort($key1, SORT_NUMERIC, SORT_DESC, $key2, SORT_NUMERIC, SORT_DESC, $newtab);
print_r($newtab);

//voila sinon je vois pas comment faire pour utiliser le multisort sur ton tableau de depart
//et si je travaille sur le tableau bout par bout c'est parce que ce que si on nomme comme ca
//les differentes composantes de ton tableau
// A( B_0( C_0, C_1, C_2, C_3), B_1(C_0, C_1, C_2, C_3))
//si tu fais directement un tri sur A tu pourras juste changer l'ordre des B et pas leur contenu//a moins de demander le tri des C_x dans la fonction de callback
//ou de faire un truc un peu bizarre avec array_walk_recursive

//voila voila ... sache que j'ai fait tout ca uniquement parce que je me faisais chier mais que
//je n'avais vraiment aucune raison de le faire surtout vu l'entrain que tu as mis a lire la doc//mais je me fais pas de soucis, si tu veux tirer partie des quelques trucs que j'ai montre tu
//vas surement etre oblige de lire la doc qu'on t'a conseille et revient pas nous demander
//ce qu'est une fonction de callback ...

//D'ailleurs dans les fonctions de callback j'utilise des test == et > qui ont pas forcement
//beaucoup de sens pour des chaines de caracteres enfin de toute facon les fonctions de callbacks
//ca sert justement a adapte le test a faire en fonction des donnees a traiter


//voila sinon je tenais a remercier ov3rdoze a qui j'ai pris son code qui fonctionne bien
//http://www.phpcs.com/infomsg_TRI-ELEMENTS_839480.aspx#2
?>
0
a2rconseil Messages postés 6 Date d'inscription jeudi 5 août 2004 Statut Membre Dernière intervention 10 novembre 2006
10 nov. 2006 à 09:13
Je te remercie beaucoup de tes amples explications et du temps que tu y as passé.
J'aprécie réellement.
Je vais essayé ca rapidement.
Désolée de ne pas être à votre hauteur...
0
Rejoignez-nous