Inversion et tri tableau multidimentionnel

Messages postés
6
Date d'inscription
jeudi 5 août 2004
Statut
Membre
Dernière intervention
10 novembre 2006
- - Dernière réponse : 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...
Afficher la suite 

10 réponses

Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
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
Commenter la réponse de cs_alexscott
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
27
0
Merci
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)
Commenter la réponse de coucou747
Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
c'est le usort je le cite pas pour rien :)
Commenter la réponse de cs_alexscott
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
27
0
Merci
Salut,

* : Mon site (articles sur la programmation et programmes)
Commenter la réponse de coucou747
Messages postés
6
Date d'inscription
jeudi 5 août 2004
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
Merci mais je n'ai pas l'impression que ca marche avec un tableau à 3 dimensions.
Commenter la réponse de a2rconseil
Messages postés
6
Date d'inscription
jeudi 5 août 2004
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
Merci mais je n'ai pas l'impression que ca marche avec un tableau à 3 dimensions.
Commenter la réponse de a2rconseil
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
27
0
Merci
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)
Commenter la réponse de coucou747
Messages postés
6
Date d'inscription
jeudi 5 août 2004
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
Désolé mais qu'est ce que tu appelles une fonction de callback?
Commenter la réponse de a2rconseil
Messages postés
55
Date d'inscription
vendredi 28 février 2003
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
<?
//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
?>
Commenter la réponse de cs_alexscott
Messages postés
6
Date d'inscription
jeudi 5 août 2004
Statut
Membre
Dernière intervention
10 novembre 2006
0
Merci
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...
Commenter la réponse de a2rconseil