Page 1 sur 1

Tri tableau 3 dimension

Posté : 13 mars 2006, 00:45
par seinto28
Bonjour à tous,
J'ai encore besoin de votre aide...

Pour une application, je dispose d'un tableau à 3 dimensions et j'aimerais pouvoir le trier selon la case 0 de la 3e D.
Voici un affichage de mon tableau:

Code : Tout sélectionner

Array ( [0] => Array ( [68] => Array ( [0] => 1 // Case à trier [1] => 71 [2] => 71 [3] => 72 ) [66] => Array ( [0] => 2 // Case à trier [4] => 66 [5] => 68 [6] => 3 ) [8] => Array ( [0] => 1 [1] => 70 [2] => 10 [3] => 3 ) ) [1] => Array ( [70] => Array ( [0] => 1 [1] => 71 [2] => 71 [3] => 72 ) [10] => Array ( [0] => 1 [1] => 70 [2] => 10 [3] => 3 ) ) [2] => Array ( [65] => Array ( [0] => 1 [1] => 71 [2] => 71 [3] => 72 ) [67] => Array ( [0] => 2 [4] => 65 [5] => 67 [6] => 3 ) ) [3] => Array ( [67] => Array ( [0] => 3 [1] => 71 [2] => 71 [3] => 72 [4] => 66 [5] => 68 [6] => 3 ) [65] => Array ( [0] => 2 [4] => 65 [5] => 67 [6] => 3 ) ) [4] => Array ( [64] => Array ( [0] => 1 [1] => 71 [2] => 71 [3] => 72 ) ) [5] => Array ( [56] => Array ( [0] => 1 [1] => 71 [2] => 71 [3] => 72 ) ) [6] => Array ( [66] => Array ( [0] => 3 [1] => 71 [2] => 71 [3] => 72 [4] => 65 [5] => 67 [6] => 3 ) [68] => Array ( [0] => 2 [4] => 66 [5] => 68 [6] => 3 ) )

Je pense qu'il faut utiliser la fonction array_multisort mais je n'y arrive pas, je peux difficilement modifier mon tableau

Cette ligne ne fonctionne pas:
array_multisort($tableau[][][0], SORT_DESC, SORT_NUMERIC);
La 1ere et 2eme dimension ne me sont plus necessaire, si ça peut apporter des solutions...

Posté : 13 mars 2006, 09:31
par mario
J'ai écrit un petit article sur mon blog.
http://mario.monsiteinfo.info/index.php ... mensionnel
Tu peux t'en inspirer :D

Posté : 13 mars 2006, 11:21
par seinto28
Merci pour cette réponse (très sympa ce blog) et ça correspond à ce que j'aimerais faire, à la différence que j'aimerais explorer une dimension de plus.

J'ai essayé ça mais je ne suis pas familier avec la commande foreach:
foreach ($tableaut as $cle => $ligne) {
	foreach ($tableau as $cle2 => $ligne2) {

               $longueur[$cle][$cle2] = $ligne2[0];
               $position[$cle][$cle2] = $ligne2[1];
               $position2[$cle][$cle2] = $ligne2[2];
	}
}
 
array_multisort($longueur, SORT_DESC, $tableau);

Posté : 13 mars 2006, 19:55
par Spols
foreach ($tableaut as $cle => [color=red]$ligne[/color]) {
	foreach ([color=red]$tableau [/color]as $cle2 => $ligne2) {

               $longueur[$cle][$cle2] = $ligne2[0];
               $position[$cle][$cle2] = $ligne2[1];
               $position2[$cle][$cle2] = $ligne2[2];
	}
}
 
array_multisort($longueur, SORT_DESC, $tableau);
ATTENTION ce doit être la meme variable

le foreach, ouvre la première dimension d'un tableau sous forme de boucle qui traitre ligne par ligne

pour un tableau à 3 dimension, il en faut donc 3 foreach imbriqué

Posté : 14 mars 2006, 00:51
par seinto28
Effectivement, ça ne pouvait pas marcher!

J'ai aussi testé ça mais ça ne fonctionne pas non plus

foreach ($tableau as $cle => $ligne) {
	foreach ($ligne as $cle2 => $ligne2) {
		foreach ($ligne2 as $cle3 => $ligne3) {
			
			$longueur[$cle][$cle2][$cle3] = $ligne3[0];

		}
	}
}
 

array_multisort($longueur, SORT_DESC, $tableau);

Posté : 14 mars 2006, 09:26
par Cyrano
J'ai aussi testé ça mais ça ne fonctionne pas non plus
Ça n'aide pas des masses si tu précises pas ce que tu obtiens, incluant les messages d'erreur s'il y en a.

Proposition : est-ce que le tri obtenu avec correspond à ce que tu cherches ?
<?php
foreach($tableau as $cle1 => $tab1)
{
    foreach($tableau[$cle1] as $cle2 => $tab2)
    {
        array_multisort($tableau[$cle1][$cle2], SORT_NUMERIC, SORT_ASC);
    }
}
?>

Posté : 14 mars 2006, 10:15
par seinto28
C'est vrai que j'aurais pu être plus précis, désolé.
Donc je n'ai pas de message d'erreur mais le tri n'est pas correct, par exemple avec ton code, j'obtiens entre-autre ça:

Code : Tout sélectionner

[69] => Array ( [69] => Array ( [0] => 1 <--- OK [1] => 71 [2] => 71 [3] => 72 ) [9] => Array ( [0] => 1 <--- OK [1] => 3 [2] => 10 [3] => 70 ) ) [68] => Array ( [68] => Array ( [0] => 1 <--- OK [1] => 71 [2] => 71 [3] => 72 ) [66] => Array ( [0] => 2 <--- OK [1] => 3 [2] => 66 [3] => 68 ) [8] => Array ( [0] => 1 <--- Probleme ça devrait etre avant le 2 du dessus [1] => 3 [2] => 10 [3] => 70 ) )
Il en va de même pour les précedents tests.

Posté : 14 mars 2006, 10:27
par Cyrano
Ok, je m'en doutais un peu, mais ton explication n'était pas évidente: en fait, tu veux classer la troisième dimensions et ensuite classer la seconde selon la plus petite valeur de la troisième.

Directement avec un array_multisort, je ne crois pas que ce soit possible. Mais par programmation, c'est tout à fait envisageable. La piste de solution serait donc schématiquement la suivante :
- un tri avec la méthode que j'ai proposée,
- ensuite l'enregistrement dans un autre tableau indexé de la clé de la seconde dimension ainsi que la plus petite valeur correspondant à cet index,
- un tri de ce second tableau,
- ensuite sur la base de ce second tableau, créer un troisième tableau avec les valeurs du premier.

Posté : 14 mars 2006, 10:46
par seinto28
Ok, je m'en doutais un peu, mais ton explication n'était pas évidente: en fait, tu veux classer la troisième dimensions et ensuite classer la seconde selon la plus petite valeur de la troisième.
Ce n'était pas très facile à expliquer pour moi aussi!!

- un tri avec la méthode que j'ai proposée,
- ensuite l'enregistrement dans un autre tableau indexé de la clé de la seconde dimension ainsi que la plus petite valeur correspondant à cet index,
- un tri de ce second tableau,
- ensuite sur la base de ce second tableau, créer un troisième tableau avec les valeurs du premier.
Je pense avoir compris ta démarche (c'est pas bete du tout), j'essaie de l'appliquer, je reviens.

Posté : 14 mars 2006, 11:39
par seinto28
Bon, c'est trop loin de mon niveau tout ça.
Voila ce que j'ai fait:
foreach($tableau as $cle1 => $tab1){
    foreach($tableau[$cle1] as $cle2 => $tab2){
	$key = $cle."|".$cle2;
        array_multisort($tableau[$cle1][$cle2], SORT_NUMERIC, SORT_DESC);
    }
} 


foreach ($tableau as $key => $valeur){     // <== erreur d'argument pour le foreach
	$key2 = explode("|",$key);

	$tableau2[$key2[0]][$key2[1]][0] = $valeur;

	foreach($tableau[$key2[0]][$key2[1]] as $position => $longueur){

			$tableau2[$key2[0]][$key2[1]][$position] = $tableau[$key2[0]][$key2[1]][$position];
	
	}
} 

array_multisort($tableau2, SORT_NUMERIC, SORT_DESC);
Je n'ai pas réussi a suivre toutes les étapes et j'ai une erreur d'argument.

Je pense que je vais revoir tout le système, je vais créer en parallele de mon tableau a 3D, un tableau simple avec les infos dont j'ai besoin. Pas très joli mais la je dois savoir faire

Posté : 14 mars 2006, 18:21
par Spols
moi je ferais cela tout à fait autrement
foreach ($tableau as $cle => $ligne) { 
    foreach ($ligne as $cle2 => $ligne2) { 
        foreach ($ligne2 as $cle3 => $ligne3) { 
             
            $tableau_tri[$cle3][$cle2][$cle] = $ligne3;
        } 
    } 
}
sort ($tableau_tri);
unset ($tableau);
foreach ($tableau_tri as $cle3 => $ligne3) { 
    foreach ($ligne3 as $cle2 => $ligne2) { 
        foreach ($ligne2 as $cle => $ligne) { 
              $tableau_tri[$cle][$cle2][$cle3] = $ligne;
        } 
    } 
}
J'inverse l'ordre des clé du tableau une première fois, je le trie et je réinverse les clés

enfin il faut tester si ca marche

Posté : 15 mars 2006, 11:13
par seinto28
Bon, j'ai fini par réécrire mon tableau et la le tri fonctionne, tout ce que j'ai essayé avant n'ayant pas marché.
Merci pour votre aide.