Aller au contenu

tri sur array php


Sujets conseillés

Posté

Bonjour à toutes et à tous,

J'ai un petit souci depuis hier et je trouve pas la soluce. Voilà, j'ai un tableau de ce type :

$array = Array([0] => Array([0] => 1 [1] => produit [2] => 18521)[1] => Array( [0] => 2 [1] => produit [2] => 42587)[2] => Array([0] => 3 [1] => produit [2] => 36524))

Je fais un foreach dessus et j'aimerais que le print_r($val) m'affiche le tableau avec un tri décroissant sur les valeurs 42587,36524,18521 donc je fais ça :

foreach($array as $val) {function cmp($val,${    return strtotime($val['2'])<strtotime($b['2'])?1:-1;};uasort($val,'cmp');print_r($val);}

Mais bien sûr cela ne fonctionne pas. Si quelqu'un ou quelqu'une a une idée pour me dépanner, ca serait formidable ?

sandy

Posté

Salut,



Réponse brute de décoffrage mais tu devrais t'en sortir sans trop de douleur...



Bon courage !



/**
* Commun_Routeur_Backbone.sortmulti([clauses [, options]]) -> Array | boolean
**/
public static function sortmulti($array, $index, $order, $natsort=FALSE, $case_sensitive=FALSE){
if(is_array($array) && count($array)>0) {
foreach(array_keys($array) as $key)
$temp[$key]=$array[$key][$index];
if(!$natsort) {
if ($order=='asc')
asort($temp);
else
arsort($temp);
}
else
{
if ($case_sensitive===true)
natsort($temp);
else
natcasesort($temp);
if($order!='asc')
$temp=array_reverse($temp,TRUE);
}
foreach(array_keys($temp) as $key)
if (is_numeric($key))
$sorted[]=$array[$key];
else
$sorted[$key]=$array[$key];
return $sorted;
}
return $sorted;
}
Posté

Merci blackpage mais ca m'a l'air un peu compliqué pour mon niveau...



J'aurais bien voulu modifier le code que j'ai donné au départ car je pense que je suis pas loin du résultat...



Personne pour trouver ce qui cloche dans mes lignes ?


Posté

Boucler sur le tableau global pour récupérer les données produit en les mettant dans un nouveau tableau, puis effectuer le tri sur ce nouveau tableau et ensuite un tri et un affichage.


Posté

Euh... ta méthode est la bonne... sauf qu'il faut utiliser usort et non uasort (qui conserve la correspondance des clés). Il y a aussi ton strtotime() qui sert à rien, c'est pour convertir une chaine de caractère (représentant une date) en entier (timestamp)



Sans manquer de respect à blackpage, c'est une manière absconse de trier un tableau en plus d’être mal optimisée...



En gros :



<?php

$val = array(
array(1, 'produit', 18521),
array(2, 'produit', 42587),
array(3, 'produit', 36524),
);


function cmp($a,$B){
if($a[2]===$b[2]) return 0;
return $a[2]<$b[2]? 1:-1;
};

usort($val,'cmp');
print_r($val);

Posté

Ton code fonctionne pour ce cas ! Merci beaucoup SSTephane.

Mais entre temps, j'ai modifié mon script et après un nouveau foreach simple du style foreach ($array as $val)
, un print_r($val) m'affiche ceci dans ma page :

Array([0] => 1 [1] => produit [2] => 18521)Array( [0] => 2 [1] => produit [2] => 42587)Array([0] => 3 [1] => produit [2] => 36524)etc...

C'est-à-dire que je n'ai plus les arrays numérotés comme avant ([0] => Array, [1] => Array etc...)

Ma question SStephane (si tu as encore un peu de temps à me consacrer) : est-il encore possible sans ces arrays numérotés d'effectuer un classement décroissant avec ton script ou c'est tout bonnement impossible comme je le pense...

Posté

Merci de t'intéresser à mon cas SStephane. Il n'y a rien de plus :



$array=array(
0 =>
array(
'0' => '1',
'1' => 'produit1',
'2' => '18521'
),
1 =>
array(
'0' => '2',
'1' => 'produit2',
'2' => '42587'
),
2 =>
array(
'0' => '3',
'1' => 'produit3',
'2' => '36524'
)
);

foreach ($array as $valeur) {

print_r($valeur);

}

Ton code de classement fonctionne très bien avant le foreach, mais en fait cela ne m'arrange pas :


je voulais donc savoir si il y avait possibilité de le faire fonctionner après le le foreach ?


Posté (modifié)

Peut être en utilisant tout simplement les valeurs de la cle 2 comme clé pour chaque "sous-tableaux" et ensuite d'utiliser ksort.


Modifié par Eric (11)
Posté

Merci Eric(11) mais ça ne me convient pas non plus pour récupérer les éléments après.



A SStephane :



1/ visiblement j'en conclue que c'est impossible de faire fonctionner ton script de classement après le foreach car il n'y a pas de numérotation des arrays, c'est ça ?



2/ Si oui, alors la solution toute bête serait que ma boucle foreach puisse récupérer l'array exactement comme avant le foreach avec les arrays numérotés ([0] => Array, [1] => Array etc...)



Mais vu mes faibles prédispositions en php je n'y suis même pas parvenue : j'ai essayé des trucs comme foreach ($array=>array as $valeur) ou foreach ($array as valeur=>$valeur)



Quelqu'un pourrait juste me dire comment faire le foreach s'il vous plaît ?

Posté

Voici le contenu du fichier test.php



<?php
$val=array(
0 =>
array(
'0' => '1',
'1' => 'produit1',
'2' => '18521'
),
1 =>
array(
'0' => '2',
'1' => 'produit2',
'2' => '42587'
),
2 =>
array(
'0' => '3',
'1' => 'produit3',
'2' => '36524'
)
);

function cmp($a,$B){
if($a[2]===$b[2]) return 0;
return $a[2]<$b[2]? 1:-1;
};

usort($val,'cmp');

foreach ($val as $valeur) {

print_r($valeur);

}
?>

L'exécution de "php test.php" donne bien ce que tu cherches ...



Array
(
[0] => 2
[1] => produit2
[2] => 42587
)
Array
(
[0] => 3
[1] => produit3
[2] => 36524
)
Array
(
[0] => 1
[1] => produit1
[2] => 18521
)

... non r_question6161.gif



A l'exception de ceci, dans le manuel de usort :




Note: Cette fonction assigne de nouvelles clés pour les éléments du paramètre array. Elle effacera toutes les clés existantes que vous aviez pu assigner, plutôt que de les trier.




Posté

Correctif : wink.gif



En supprimant ta boucle foreach en fin de script



foreach ($val as $valeur) {

print_r($valeur);

}

et en la remplaçant par ceci, tout simplement



print_r($val)

on obtient :



Array
(
[0] => Array
(
[0] => 2
[1] => produit2
[2] => 42587
)

[1] => Array
(
[0] => 3
[1] => produit3
[2] => 36524
)

[2] => Array
(
[0] => 1
[1] => produit1
[2] => 18521
)

)

Donc là tu gardes le numéro de tes array (0, 1, 2), mais ce ne sont pas les mêmes que ceux d'origine... :(

Posté (modifié)

Merci pour ta réponse Dan mais ça j'avais compris, ca ok ça marche.

Maintenant ce que je cherche c'est de laisser le foreach et de mettre un code php de tri ici (en rouge) :

$array=array(0 =>array('0' => '1','1' => 'produit1','2' => '18521'),1 =>array('0' => '2','1' => 'produit2','2' => '42587'),2 =>array('0' => '3','1' => 'produit3','2' => '36524'));foreach ($array as $valeur) {//CODE DE TRI ICIprint_r($valeur);}

C'est possible tu crois Dan ?

1/ Moi il ne me semble pas car mon foreach ne génère pas des arrays numérotés ([0] => Array, [1] => Array etc...) donc classement impossible. Dis moi Dan si j'ai raison ou tort ?

2/ Si c'est pas possible alors il faut que mon Foreach génère des arrays numérotés (en fait exactement comme l'array avant le foreach. Et ça, j'y arrive pas, pourtant ça doit être tout simple non ?

Je sais je suis chiante ce soir...

Modifié par sandrinoo
Posté

Non, ce n'est pas possible car le foreach n'a qu'une sous-array à la fois, donc rien à trier !



Tu veux que tes arrays soient numérotées comme à l'origine ?

Posté

Merci Dan pour ta réponse.



Ok, si ce n'est pas possible, c'est bien ce que je pensais.



Il faudrait donc que mes arrays soient numérotés comme à l'origine mais après le foreach


Et là je n'y arrive pas : j'ai essayé des trucs comme foreach ($array=>array as $valeur) ou foreach ($array as valeur=>$valeur) mais je ne suis pas assez calée...



Dan, comment faire ce foreach pour qu'il me donne les arrays numérotés comme à l'origine ?


Posté

uasort($val,'cmp');

uasort() à la place de usort() mais ton foreach sera executé dans l'ordre "réordonné".

SI tu veux boucler dans l'ordre "naturel" des clés, n'utilise pas un foreach mais un for, voilà tout :

<?php

$val = array(

array(1, 'produit', 18521),

array(2, 'produit', 42587),

array(3, 'produit', 36524),

);

function cmp($a,$B){

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

return $a[2]<$b[2]? 1:-1;

};

uasort($val,'cmp');

print "<h2>foreach:</h2>";

foreach($val as $k=>$arr){

print '<hr>';

print $k.' : ';

print_r($arr);

}

print "<h2>for:</h2>";

for($i=0;$i<count($val);++$i){

print '<hr>';

print $i.' : ';

print_r($val[$i]);

}

Ca fonctionne, par contre, si tu as un successeur sur ce script, m'est avis qu'il risque de te maudire pour ça, c'est quand même une subtilité pourrie de php de pouvoir ordonner un tableau dans un ordre différent de clés entières smile.gif

Je pense qu'il y a plus simple à faire, quel que soit ton objectif (que l'on ne connait pas wink.gif)

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...