[RESOLU] Classer des tableaux en PHP

Petit nouveau ! | 4 Messages

20 janv. 2015, 14:27

Bonjour,

Je m'adresse à vous car j'ai un petit soucis sur lequel je planche :'(

Je dispose de données repertoriées dans differents tableaux (tableauNom, tableauPrenom, tableauAge...) dans lesquels sont rangées les differentes infos.
Ainsi, tableauNom[0] s'associe à tableauPrenom[0] et ainsi de suite.

Mon but est de pouvoir faire des liens permettant de classer les données celon le nom, ou bien l'age, ou bien le prenom... (Au choix de l'utilisateur) et de garder les données dans le bon ordre.
Ainsi, j'ai réussi, grâce à la fonction array_multisort() et en l'associant avec la fonction array_combine() à faire ce que je voulais, mais cela ne fonctionne que pour 2 tableaux.

Auriez vous une solution qui puisse fonctionner sur les 5 tableaux à la fois ?

Merci à vous.

ViPHP
ViPHP | 928 Messages

20 janv. 2015, 16:52

Salut,
tu ne pourrais pas plutôt avoir dans un premier temps un tableau du genre :
$data = array(
   0 => array('nom' => 'Smith', 'prenom' => 'John', 'age' => 42),
   1 => array('nom' => 'Poutine', 'prenom' => 'Vladimir', 'age' => 666),
);
Car ça serait beaucoup plus simple de travailler dessus, non seulement les données seraient organisées de façon plus logiques, mais en plus un simple usort() te permettrait de trier ce que tu veux comme tu le veux.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

20 janv. 2015, 17:54

Effectivement, l'approche proposée par Genova me semble plus efficace.

Voila comment je le ferrai pour transformer tes données vers un tableau unique à plusieurs dimensions :
<?php
$tableauInfos=array();

foreach ($tableauNom as $id => $nom) {
     $tableauInfos[$id]['nom'] = $tableauNom[$id];
     $tableauInfos[$id]['prenom'] = $tableauPrenom[$id];
     $tableauInfos[$id]['age'] = $tableauAge[$id];
}

var_dump($tableauInfos);
Quand tout le reste a échoué, lisez le mode d'emploi...

Petit nouveau ! | 4 Messages

20 janv. 2015, 18:54

Merci pour la piste Genova.

Comme tu m'as conseillé, j'ai tout changé pour obtenir un tableau de tel sorte que
$tableauFinal[$i][0] = Nom
$tableauFinal[$i][1] = Prenom
$tableauFinal[$i][2] = Age
etc...

J'ai ensuite essayé de mettre en application la fonction usort() qui à l'air assez complexe:
function cmp($a, $b)
{
	return strcmp($a[0], $b[0]);
}
usort($tableauFinal, "cmp");										
while (list($key, $value) = each($tableauFinal)) 
{
   echo ''.$value[0].' - '.$value[1].' - '.$value[2].' - '.$value[3].'<br/>';
}
J'ai testé un peu au pif en regardant les exemples du manuel, et ca fonctionne :D
Par contre, je comprend rien du tout. (a quoi correspond $b, comment il effectue son trie...).
Et j'ai beau lire et relire le manuel, je comprend pas le truc.
Tu pourrais juste m'expliquer ce que j'ai fais par hasard ?

ViPHP
ViPHP | 928 Messages

21 janv. 2015, 00:33

En gros usort() tu lui passes ton tableau et une fonction en paramètre, et il va utiliser cette fonction pour comparer les éléments.

Ta fonction va donc être appelée plusieurs fois, pour comparer chaque élément de ton tableau 2 par 2. Le $a correspond a un élément de ton tableau, et le $b correspond à un autre. Le rôle de ta fonction va être de dire si $a doit être classé avant $b, ou l'inverse, ce qui permettra donc de trier le tableau comme tu veux.

Si $a est inférieur à $b (c'est à dire que $a doit être classé avant $b), alors tu retournes -1, sinon tu retournes 1. Si tu retournes 0, c'est que les deux éléments sont identiques (même prénom par exemple).

strcmp() est justement très pratique à utiliser avec usort() puisque c'est une fonction qui retourne -1 si la première chaine est inférieur à la seconde, sinon 1 (ou 0 si les deux chaînes sont identiques).

Et à partir de PHP 5.3 tu peux faire ça directement, plutôt que de déclarer une fonction :
usort($tableauFinal, function($a, $b)
{
        return strcmp($a[0], $b[0]);
});  

Et je te conseil aussi si possible de nommer tes clefs pour les prénoms, noms et ages de manière littéraire plutôt qu'avec des chiffres, c'est beaucoup plus simple pour s'y retrouver après ;)
usort($tableauFinal, function($a, $b)
{
        return strcmp($a['name'], $b['name']);
});

Petit nouveau ! | 4 Messages

21 janv. 2015, 12:54

Merci pour ta réponse Genova :D
J'aurais par contre une dernière question: est-il possible d'effectuer un tri sur un deuxième caractère si la valeur retournée vaut 0 ?
Par exemple, si deux personnes ont le même nom, faire une classement en fonction du prénom ?

ViPHP
ViPHP | 928 Messages

21 janv. 2015, 13:09

Bien sur :
usort($tableauFinal, function($a, $b)
{
	$cmpNom = strcmp($a['nom'], $b['nom']);
	if ($cmpNom != 0)
		return $cmpNom;

	return strcmp($a['prenom'], $b['prenom']);
});

Petit nouveau ! | 4 Messages

21 janv. 2015, 13:12

Merci beaucoup Génova.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

21 janv. 2015, 13:13

J'aurais par contre une dernière question: est-il possible d'effectuer un tri sur un deuxième caractère si la valeur retournée vaut 0 ?
Par exemple, si deux personnes ont le même nom, faire une classement en fonction du prénom ?
Si tu fais d'abord un classement par prénom de l'ensemble de ton tableau puis un classement par nom, il y a des chances que ça fonctionne je pense vu que la comparaison s'effectue 2 par 2.
Quand tout le reste a échoué, lisez le mode d'emploi...