Page 1 sur 1

Optimisation double tri sur un tableau

Posté : 12 janv. 2009, 18:40
par AB
Bonjour,

Voilà j'ai un tableau qui attribue 1 aux garçons et 2 aux filles (comme pour le premier chiffre du numéro de la sécurité sociale)
$tab['alain'] = 1;
$tab['alex'] = 1;
$tab['anne'] = 2;
$tab['philippe'] = 1;
$tab['catherine'] = 2;
$tab['caroline'] = 2;
$tab['anne marie'] = 2;
$tab['gwendoline'] = 2;
$tab['georges'] = 1;
et je voudrais pouvoir faire un tri sur les index et sur les valeurs pour obtenir par exemple ceci

Code : Tout sélectionner

anne 2 anne marie 2 caroline 2 catherine 2 gwendoline 2 alain 1 alex 1 georges 1 philippe 1
Pour l'instant j'ai fait ça
$tab['alain'] = 1;
$tab['alex'] = 1;
$tab['anne'] = 2;
$tab['philippe'] = 1;
$tab['catherine'] = 2;
$tab['caroline'] = 2;
$tab['anne marie'] = 2;
$tab['gwendoline'] = 2;
$tab['georges'] = 1;

function Tri ($tab,$ordrekey = 'asc',$ordrevalue = 'asc') 
    {
	$temp = array();
	$tab_tri = array();

	$ordrekey == 'asc' ? ksort($tab) : krsort($tab);

	// Crée un tableau multidimentionnel groupé par valeurs 
	foreach($tab as $key => $value) $temp[$value][$key] = $value;

	$ordrevalue == 'asc' ? ksort($temp) : krsort($temp);

	foreach($temp as $value) $tab_tri += $value;
	
	return $tab_tri;
	}

// Affichage
foreach (Tri($tab,'asc','desc') as $key => $value) echo $key.'&nbsp;'.$value.'<br />';
Cela fonctionne mais bon je me dis qu'il y peut-être plus hi-tech et mieux optimisé ?
Vous avez des suggestions ?

Posté : 19 janv. 2009, 03:14
par rolusseum
Ben, j'ai trouvé ça.
[url]
http://www.manuelphp.com/php/function.array-filter.php
[/url]


[php]
function impair($var)
{
return ($var % 2 == 1);
}

function pair($var)
{
return ($var % 2 == 0);
}

$tab['alain'] = 1;
$tab['alex'] = 1;
$tab['anne'] = 2;
$tab['philippe'] = 1;
$tab['catherine'] = 2;
$tab['caroline'] = 2;
$tab['anne marie'] = 2;
$tab['gwendoline'] = 2;
$tab['georges'] = 1;

ksort($tab);

echo "Hommes :\n";
echo '<pre>';
print_r(array_filter($tab, "impair"));
echo '</pre>';

echo "Femmes :\n";
echo '<pre>';
print_r(array_filter($tab, "pair"));
echo '</pre>';


[/php]

Posté : 19 janv. 2009, 04:06
par AB
Merci de ta réponse mais ta solution ne pourrait pas fonctionner si j'avais un nombre indéterminé de groupes (je n'en ai mis que deux mais ce n'était qu'un exemple) et d'autre part elle suppose que les valeurs soient numériques. Donc ta solution n'est pas mauvaise mais trop spécifique.

Posté : 19 janv. 2009, 04:21
par Calimero
Une question : tu es obligé de garder cette structure "à plat" type table SQL ?

Car si tu peux t'en éloigner un peu, j'aurai bien imaginé un truc du genre :
$code_valeurs=array(
  2 => array(
     'anne',
     'virginie',
     'laure',
  ),
  1 => array(
    'pierre',
    'jacques',
    'arnaud',
  ),
);
Qui devient de fait beaucoup plus facile à trier :
foreach($code_valeurs as $code=>$valeurs){
  natsort($valeurs);
}
ksort($code_valeurs); // faire la bascule avec krsort() ici si besoin

Posté : 19 janv. 2009, 05:47
par AB
Une question : tu es obligé de garder cette structure "à plat" type table SQL ?

Car si tu peux t'en éloigner un peu, j'aurai bien imaginé un truc du genre :
$code_valeurs=array(
  2 => array(
     'anne',
     'virginie',
     'laure',
  ),
  1 => array(
    'pierre',
    'jacques',
    'arnaud',
  ),
);
Qui devient de fait beaucoup plus facile à trier :
foreach($code_valeurs as $code=>$valeurs){
  natsort($valeurs);
}
ksort($code_valeurs); // faire la bascule avec krsort() ici si besoin
Oui effectivement s'il n'y avait que du tri à faire ce serait plus performant mais cette structure de tableau m'handicaperait pour le reste...
Et puis après vérification cela ne fonctionne pas du tout (les tris ne se font pas dans la boucle) :-k

Posté : 19 janv. 2009, 06:41
par naholyr
Et puis après vérification cela ne fonctionne pas du tout (les tris ne se font pas dans la boucle) :-k
Il suffit d'indiquer à foreach de travailler par référence : "foreach($code_valeurs as $code=>&$valeurs){ ".

Tu as essayé simplement natsort() + ksort() (l'un après l'autre) ?

Posté : 19 janv. 2009, 15:19
par AB
Il suffit d'indiquer à foreach de travailler par référence

Oui j'aurais dû y penser mais je ne me suis pas trop attardé car cette structure de tableau ne m'arrange pas. Cela dit si l'opération de tri était prépondérante j'aurais intérêt à l'adopter.
Tu as essayé simplement natsort() + ksort() (l'un après l'autre) ?
C'est la première chose à laquelle j'avais pensé :wink: