Trier un tableau en PHP

Besoin d'aide sur un cas particulier

Le problème exposé dans ce sujet a été résolu.

Bonsoir,

J'ai commencé il y a quelques temps un petit site perso en PHP, mais il y a de nombreuses subtilités dans ce langage (qui ne m'est pas encore très familier) qui me troublent, notamment au sujet des tableaux.

Prenons un tableau défini ainsi :

1
2
3
4
5
6
7
8
$tab = array
(
    "premier" => 4,
    "second" => 2,
    "machin" => 3,
    "chose" => 1,
    "truc" => 5,
);

J'aimerais pouvoir trier ces éléments d'après leurs valeurs, mais (et c'est ça qui me pose problème) il faudrait que les éléments "premier" et "second" restent (respectivement) en première et seconde position.

Il faudrait donc au final obtenir le tableau suivant :
{ ["premier"]=> int(4) ["second"]=> int(2) ["truc"]=> int(5) ["machin"]=> int(3) ["chose"]=> int(1) }.

Pour le moment, j'ai ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
uksort($tab, function($a, $b) use($tab)
{
    if($b == "premier")
        return 1;
    if($a == "premier")
        return -1;
    if($b == "second")
        return 1;
    if($a == "second")
        return -1;

    return $tab[$b] - $tab[$a];
});

Et ça fonctionne. Mais je me dis que c'est pas très beau, et probablement pas la meilleure manière d'y procéder.

Donc ma question : comment conserver la position de certains éléments ? Faudrait-il modifier manuellement l'index de ceux-ci par la suite ? Si oui, comment ?

+0 -0

Salut !

Pour ma part, plutôt que de faire un tri biaisé, je mettrais les deux premiers éléments dans des variables séparées, et si vraiment je devais les passer dans un tableau avec les autres valeurs, j'utiliserais la fonction array_unshift() — après avoir trié mon tableau.

+1 -0

Pour ma part, plutôt que de faire un tri biaisé, je mettrais les deux premiers éléments dans des variables séparées […]

Ymox

Oui j'y avait pensé, mais en fait cela ne faisait que compliqué la chose, puisqu'en réalité il s'agit d'un tableau avec de nombreuses colonnes, triable par lignes, mais aussi par colonnes. Séparer ces valeurs compliquerait la chose pour ce qui est du tri des colonnes.

J'ai regardé du côté de array_unshift, mais comme mon tableau est associatif, j'ai essayé avec le simple opérateur + :

1
2
3
4
uksort(/* ... */);

$tab = array("second" => $tab["second"]) + $tab;
$tab = array("premier" => $tab["premier"]) + $tab;

Et étrangement, ça marche. J'aurais pu m'attendre à ce que l'élément soit simplement copié au début plutôt que déplacé, mais visiblement non. Serait-ce alors la meilleure manière ?

En effet l'opérateur + fonctionne, ce qui donne un code assez court :

1
2
3
4
5
6
<?php
unset(array_keys($tab)[0]);
unset(array_keys($tab)[1]);
arsort($tab);
$tab = array("premier" => $tab["premier"]) + array("second" => $tab["second"]) + $tab;
print_r($tab); // Array ( [premier] => 4 [second] => 2 [truc] => 5 [machin] => 3 [chose] => 1 ) 

Pour les fonctions de tri des tableaux en PHP : http://php.net/manual/fr/array.sorting.php

+1 -0

Sauf que les unset ne sont même pas utiles ici, si ? Avec ou sans, j'ai le même résultat.

(HS : Pour mon projet, je suis obligé d'utiliser uksort, car mon algorithme de tri est en réalité plus complexe que celui que j'ai mis ici.)

On peut regrouper certaines "instructions" (2 * array_unshift => array_splice).

C'est un brin laid mais :

1
$tab = array_splice($tab, 0, 2) + (function (array &$tab) { ksort($tab); return $tab; })($tab);

Et encore pire si :

1
$tab = array_splice($tab, 0, 2) + (function () use(&$tab) { ksort($tab); return $tab; })();
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte