Cette question est destinée à servir de référence pour les questions sur le tri des tableaux en PHP. Il est facile de penser que votre cas particulier est unique et mérite une nouvelle question, mais la plupart sont en fait des variantes mineures de l'une des solutions de cette page.
Si votre question est fermée en tant que double de celle-ci, veuillez demander à ce que votre question ne soit rouverte que si vous pouvez expliquer pourquoi elle diffère sensiblement de toutes les réponses ci-dessous.
Comment trier un tableau en PHP?
Comment trier un tableau complexe en PHP?
Comment trier un tableau d'objets en PHP?
Pour la réponse pratique en utilisant les fonctions existantes de PHP, voir 1., pour la réponse académique détaillée sur les algorithmes de tri (quelles fonctions PHP implémentent et dont vous pourriez avoir besoin pour des cas vraiment très complexes), voir 2.
Réponses:
Tableaux unidimensionnels de base
Fonctions de tri applicables:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
La différence entre celles-ci est simplement de savoir si les associations de valeurs-clés sont conservées (les
a
fonctions " "), si elles trient de bas en haut ou inversement ("r
"), si elles trient des valeurs ou des clés ("k
") et comment elles comparent les valeurs. ("nat
" vs normal). Voir http://php.net/manual/en/array.sorting.php pour un aperçu et des liens vers plus de détails.Tableaux multidimensionnels, y compris les tableaux d'objets
Si vous souhaitez trier
$array
par la clé 'foo' de chaque entrée, vous avez besoin d'une fonction de comparaison personnalisée . Les fonctions cisort
- dessus et connexes fonctionnent sur des valeurs simples qu'ils savent comparer et trier. PHP ne se contente pas de "savoir" quoi faire avec une valeur complexe commearray('foo' => 'bar', 'baz' => 42)
; vous devez donc le dire.Pour ce faire, vous devez créer une fonction de comparaison . Cette fonction prend deux éléments et doit renvoyer
0
si ces éléments sont considérés comme égaux, une valeur inférieure à0
si la première valeur est inférieure et une valeur supérieure à0
si la première valeur est supérieure. C'est tout ce qu'il faut:Souvent, vous souhaiterez utiliser une fonction anonyme comme rappel. Si vous souhaitez utiliser une méthode ou une méthode statique, consultez les autres façons de spécifier un rappel en PHP .
Vous utilisez ensuite l'une de ces fonctions:
usort
uasort
uksort
Encore une fois, ils ne diffèrent que par le fait de conserver les associations clé-valeur et de les trier par valeurs ou clés. Lisez leur documentation pour plus de détails.
Exemple d'utilisation:
usort
prendra deux éléments du tableau et appellera votrecmp
fonction avec eux. Ainsicmp()
sera appelé avec$a
commearray('foo' => 'bar', 'baz' => 42)
et$b
comme un autrearray('foo' => ..., 'baz' => ...)
. La fonction retourne ensuite àusort
laquelle des valeurs était la plus grande ou si elles étaient égales.usort
répète ce processus en passant différentes valeurs pour$a
et$b
jusqu'à ce que le tableau soit trié. Lacmp
fonction sera appelée plusieurs fois, au moins autant de fois qu'il y a de valeurs$array
, avec différentes combinaisons de valeurs pour$a
et à$b
chaque fois.Pour vous habituer à cette idée, essayez ceci:
Tout ce que vous avez fait était de définir une façon personnalisée de comparer deux articles, c'est tout ce dont vous avez besoin. Cela fonctionne avec toutes sortes de valeurs.
Soit dit en passant, cela fonctionne sur n'importe quelle valeur, les valeurs n'ont pas à être des tableaux complexes. Si vous souhaitez effectuer une comparaison personnalisée, vous pouvez également le faire sur un simple tableau de nombres.
sort
trie par référence et ne renvoie rien d'utile!Notez que le tableau est trié sur place , vous n'avez pas besoin d'attribuer la valeur de retour à quoi que ce soit.
$array = sort($array)
remplacera le tableau partrue
, pas par un tableau trié. Fonctionne justesort($array);
.Comparaisons numériques personnalisées
Si vous souhaitez trier par la
baz
clé, qui est numérique, il vous suffit de:Grâce au PoWEr OF MATH, cela renvoie une valeur <0, 0 ou> 0 selon qu'elle
$a
est inférieure, égale ou supérieure à$b
.Notez que cela ne fonctionnera pas bien pour les
float
valeurs, car elles seront réduites à unint
et perdront leur précision. Utilisez explicite-1
,0
et les1
valeurs de retour à la place.Objets
Si vous avez un tableau d'objets, cela fonctionne de la même manière:
Les fonctions
Vous pouvez faire tout ce dont vous avez besoin dans une fonction de comparaison, y compris les fonctions d'appel:
Cordes
Un raccourci pour la première version de comparaison de chaînes:
strcmp
fait exactement ce qu'on attend d'cmp
ici, il revient-1
,0
ou1
.Opérateur de vaisseau spatial
PHP 7 a introduit l' opérateur de vaisseau spatial , qui unifie et simplifie égal / plus petit / plus grand que les comparaisons entre les types:
Tri par plusieurs champs
Si vous souhaitez trier principalement par
foo
, mais sifoo
est égal pour deux éléments, trier parbaz
:Pour ceux qui le connaissent, cela équivaut à une requête SQL avec
ORDER BY foo, baz
.Voir également cette version abrégée très soignée et comment créer dynamiquement une telle fonction de comparaison pour un nombre arbitraire de clés .
Tri dans un ordre manuel et statique
Si vous souhaitez trier les éléments dans un "ordre manuel" comme "foo", "bar", "baz" :
Pour tout ce qui précède, si vous utilisez PHP 5.3 ou supérieur (et vous devriez vraiment), utilisez des fonctions anonymes pour un code plus court et pour éviter d'avoir une autre fonction globale flottant:
Voilà comment le tri simple d'un tableau multidimensionnel complexe peut être. Encore une fois, pensez simplement en termes d' enseignement à PHP pour savoir lequel des deux éléments est "supérieur" ; laissez PHP faire le tri réel.
Aussi pour tout ce qui précède, pour basculer entre l'ordre croissant et décroissant, permutez simplement les arguments
$a
et$b
. Par exemple:Tri d'un tableau en fonction d'un autre
Et puis il y a le particulier
array_multisort
, qui vous permet de trier un tableau en fonction d'un autre:Le résultat attendu ici serait:
Utilisez
array_multisort
pour vous y rendre:Depuis PHP 5.5.0, vous pouvez utiliser
array_column
pour extraire une colonne d'un tableau multidimensionnel et trier le tableau sur cette colonne:Depuis PHP 7.0.0, vous pouvez également extraire des propriétés d'un tableau d'objets.
la source
array_flip()
d'utiliser la recherche de position plus rapide, par exemple$order[$a['foo']]
au lieu dearray_search($a['foo'], $order)
.Eh bien, la plupart des méthodes de base sont déjà couvertes par la décomposition , j'essaierais d'examiner d'autres types de tri
Tri avec SPL
SplHeap
Production
SplMaxHeap
La classe SplMaxHeap fournit les principales fonctionnalités d'un tas, en gardant le maximum au sommet.
SplMinHeap
Autres types de tri
Tri des bulles
De l'article Wikipedia sur Bubble Sort:
Tri de sélection
Extrait de l'article Wikipédia sur le tri par sélection:
Tri par insertion
Extrait de l'article Wikipedia sur le tri par insertion:
Shellsort
De l'article Wikipedia sur Shellsort:
Tri par peigne
Extrait de l'article Wikipédia sur le tri par peigne:
Tri par fusion
De l'article Wikipedia sur le tri par fusion:
Tri rapide
Extrait de l'article Wikipedia sur Quicksort:
Tri par permutation
Extrait de l'article Wikipedia sur le tri par permutation:
Tri Radix
Extrait de l'article Wikipedia sur Radix sort:
la source
O(n^2)
comparaisons si nous utilisons uniquement le premier élément comme pivot)Tri stable
Disons que vous avez un tableau comme celui-ci:
Et maintenant, vous voulez trier uniquement la première lettre:
Le résultat est le suivant:
Le genre n'était pas stable!
L'observateur averti a peut-être remarqué que l'algorithme de tri de tableau (QuickSort) n'a pas produit de résultat stable et que l'ordre d'origine entre les mots de la même première lettre n'a pas été conservé. Ce cas est trivial et nous aurions dû comparer la chaîne entière, mais supposons que votre cas d'utilisation soit plus compliqué, comme deux tris consécutifs sur des champs différents qui ne devraient pas s'annuler mutuellement.
La transformation schwartzienne
La transformée de Schwartzian , également appelée idiome décorer-trier-décorer, effectue un tri stable avec un algorithme de tri intrinsèquement instable.
Tout d'abord, vous décorez chaque élément du tableau avec un autre tableau comprenant une clé primaire (la valeur) et une clé secondaire (son index ou sa position):
Cela transforme le tableau en ceci:
Maintenant, nous ajustons l'étape de comparaison; nous comparons à nouveau la première lettre, mais si elles sont identiques, la clé secondaire est utilisée pour conserver l'ordre d'origine:
Ensuite, on décore:
Le résultat final:
Et la réutilisation?
Vous avez dû réécrire votre fonction de comparaison pour travailler avec les éléments de tableau transformés; vous ne voudrez peut-être pas modifier vos fonctions de comparaison délicates, alors voici un wrapper pour la fonction de comparaison:
Écrivons l'étape de tri à l'aide de cette fonction:
Voila! Votre code de comparaison vierge est de retour.
la source
Depuis PHP 5.3 avec fermetures, il est également possible d'utiliser une fermeture pour déterminer l'ordre de votre tri.
Par exemple, en supposant que $ array est un tableau d'objets qui contiennent une propriété month.
la source
LINQ
Dans .NET, LINQ est fréquemment utilisé pour le tri, qui fournit une syntaxe beaucoup plus agréable que les fonctions de comparaison, en particulier lorsque les objets doivent être triés par plusieurs champs. Il existe plusieurs ports de LINQ vers PHP, y compris la bibliothèque YaLinqo *. Avec lui, les tableaux peuvent être triés sur une seule ligne sans écrire de fonctions de comparaison complexes.
Les comparaisons peuvent être personnalisées davantage en passant un rappel comme deuxième argument, par exemple:
Voici
'$v->count'
un raccourci pourfunction ($v) { return $v->count; }
(l'un ou l'autre peut être utilisé). Ces chaînes de méthodes renvoient des itérateurs, les itérateurs peuvent être transformés en tableaux en ajoutant->toArray()
à la fin si nécessaire.En interne,
orderBy
et des méthodes connexes appellent tableau appropriées fonctions de tri (uasort
,krsort
,multisort
,usort
etc.).LINQ contient de nombreuses autres méthodes inspirées de SQL: filtrage, regroupement, jointure, agrégation, etc. Il convient mieux aux cas où des transformations complexes sur des tableaux et des objets doivent être effectuées sans s'appuyer sur des bases de données.
* développé par mes soins, consultez le fichier Lisez-moi pour plus de détails et une comparaison avec d'autres ports LINQ
la source
Tri multidimensionnel par valeur de clé
Tri naturel d'un tableau multidimensionnel par valeur de clé et conserve également l'ordre d'origine (ne mélangez pas les clés principales):
Cas de test:
la source
Il est très pratique de trier les tableaux avec la fonction triée de Nspl :
Tri de base
Tri par résultat de fonction
Tri du tableau multidimensionnel
Tri d'un tableau d'objets
Tri avec fonction de comparaison
Vous pouvez voir tous ces exemples ici .
la source
Si vous souhaitez commander par valeur clé, vous pouvez le faire sur une ligne, élégante et claire. Cette commande se fera par le prix croissant. Utilise array_multisort et array_column.
produire
la source
Cette page est très complète, mais je veux ajouter un peu plus sur l'utilité impressionnante de l'opérateur de vaisseau spatial (opérateur de comparaison à trois voies) - un bel enfant de PHP7 +.
Utilisation de l'opérateur de vaisseau spatial pour implémenter plusieurs conditions de tri
Cela fait de grands progrès dans la réduction du gonflement du code et l'amélioration de la lisibilité.
Lorsque vous écrivez votre fonction de tri personnalisé (
usort()
/uasort()
/uksort()
) pour traiter plusieurs conditions, il vous suffit d'écrire des tableaux équilibrés de chaque côté de l'opérateur et de renvoyer le résultat. Plus de blocs de condition imbriqués ni de retours multiples.Les éléments des deux côtés de l'opérateur seront parcourus de gauche à droite, un par un, et retournant l'évaluation dès qu'une non-liaison est rencontrée ou lorsque les éléments ont tous été comparés.
Exemples de données pour mes démonstrations:
Démonstrations (pour éviter le gonflement de la page Stackoverflow, veuillez consulter le lien de démonstration pour les sorties):
Logique de tri:
flotteur ASC
Logique de tri:
ASC booléen
Logique de tri:
natString ASC
Cette syntaxe vous permet de trier les valeurs, les résultats fonctionnels, les données profondément imbriquées et la direction de tri d'une manière élégante. Cela vaut vraiment la peine de mettre votre ceinture d'outils php ... pour les cas où vous traitez des données non liées à une base de données - car bien sûr, SQL serait une technique beaucoup plus judicieuse.
À votre propre discrétion, à partir de PHP7.4, vous pouvez utiliser la syntaxe des flèches avec ces fonctions anonymes. Même script avec la syntaxe des flèches .
la source
Si quelqu'un veut une solution plus simple pour manipuler les tableaux, utilisez simplement le package Laravel Collection qui a une fonction sortBy implémentée qui permet de trier simplement par clés.
c'est-à-dire, afin de trier d'abord par a, puis b, puis c, la bonne clause serait
https://packagist.org/packages/tightenco/collect
la source
Il y a plusieurs façons de trier un tableau.Je mentionnerai quelques méthodes pour faire cette tâche.Pour commencer, je donnerai un tableau entier qui s'appelle '$ nombres'.
C'est la manière normale de créer un tableau. Supposons que je veuille trier ce tableau dans l'ordre croissant, pour cela, la méthode 'sort ()' peut être utilisée.
Considérez maintenant la sortie de cela,
Vous pouvez voir que le tableau des numéros imprimés est trié. Si vous voulez que ce tableau de nombres soit trié par ordre décroissant, la méthode 'rsort ()' peut être utilisée pour cette tâche.
considérer la sortie ..
Maintenant, le tableau est trié dans l'ordre décroissant.Ok, considérons un tableau associatif.Je donnerai un tableau associatif (tableau associatif signifie que, un tableau dont chaque index a une valeur de clé unique.) Comme ceci,
Donc, maintenant je veux trier ce tableau dans l'ordre croissant en fonction de leur valeur. La méthode 'asort ()' peut être utilisée pour cela.
Si vous triez l'ordre décroissant en fonction de leur valeur, la méthode 'arsort ()' peut être utilisée. Supposons que vous souhaitiez trier ce tableau en fonction de leur valeur de clé. Dans ce cas, la méthode 'ksort ()' peut être utilisée.
Considérez maintenant la sortie.
Le tableau est maintenant trié en fonction de sa valeur de clé.Si vous souhaitez trier le tableau en ordre décroissant en fonction de sa valeur de clé, la méthode 'krsort ()' peut être utilisée.
Maintenant, le tableau associatif est trié par ordre décroissant en fonction de leur valeur de clé.
Ce sont les quelques méthodes pour trier un tableau dans l'ordre croissant ou décroissant en php.J'espère que vous pourriez avoir une idée.Merci!
la source
Le plus simple est d'utiliser la fonction usort pour trier les tableaux sans boucle: voici un exemple:
Cela triera par ordre décroissant:
Cela triera dans l'ordre suivant:
la source