Compte tenu de ce tableau:
$inventory = array(
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
Je voudrais trier $inventory
les éléments par prix pour obtenir:
$inventory = array(
array("type"=>"pork", "price"=>5.43),
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
);
Comment puis-je faire ceci?
Réponses:
Vous avez raison, la fonction que vous recherchez est
array_multisort()
.Voici un exemple tiré directement du manuel et adapté à votre cas:
la source
PHP 7+
Depuis PHP 7, cela peut être fait de manière concise en utilisant
usort
une fonction anonyme qui utilise l' opérateur du vaisseau spatial pour comparer les éléments.Vous pouvez faire un tri croissant comme ceci:
Ou un tri décroissant comme celui-ci:
Pour comprendre comment cela fonctionne, notez que
usort
prend une fonction de comparaison fournie par l'utilisateur qui doit se comporter comme suit (à partir des documents):Et notez également que
<=>
, l'opérateur du vaisseau spatial,c'est exactement ce qui a
usort
besoin. En fait, presque toute la justification donnée pour ajouter<=>
au langage dans https://wiki.php.net/rfc/combined-comparison-operator est qu'ilPHP 5.3+
PHP 5.3 a introduit des fonctions anonymes, mais n'a pas encore d'opérateur de vaisseau spatial. Nous pouvons toujours utiliser
usort
pour trier notre tableau, mais c'est un peu plus détaillé et plus difficile à comprendre:Notez que bien qu'il soit assez courant que les comparateurs traitant des valeurs entières renvoient simplement la différence des valeurs, comme
$item2['price'] - $item1['price']
, nous ne pouvons pas le faire en toute sécurité dans ce cas. C'est parce que les prix sont des nombres à virgule flottante dans l'exemple du poseur de questions, mais la fonction de comparaison à laquelle nous passonsusort
doit renvoyer des entiers pourusort
fonctionner correctement:C'est un piège important à garder à l'esprit lors de l'utilisation
usort
en PHP 5.x! Ma version originale de cette réponse a fait cette erreur et pourtant j'ai accumulé dix votes positifs sur des milliers de vues apparemment sans que personne ne remarque le bug sérieux. La facilité avec laquelle les astucieux comme moi peuvent bousiller les fonctions du comparateur est précisément la raison pour laquelle l'opérateur de vaisseau spatial plus facile à utiliser a été ajouté au langage en PHP 7.la source
uasort
. Après avoir regardé les documents, cependant, cette réponse est toujours correcte dans ce cas . Dans l'exemple de l'OP, le tableau à trier a des index numériques séquentiels plutôt que des index de chaîne, c'est doncusort
plus approprié. L'utilisationuasort
sur un tableau indexé séquentiellement entraînera un tableau trié qui n'est pas ordonné par ses index numériques, de sorte que le premier élément vu dans uneforeach
boucle ne l'est pas$your_array[0]
, ce qui est peu susceptible d'être un comportement souhaitable.Alors que d'autres ont correctement suggéré l'utilisation de
array_multisort()
, pour une raison quelconque, aucune réponse ne semble reconnaître l'existence dearray_column()
ce qui peut grandement simplifier la solution. Donc, ma suggestion serait:la source
Étant donné que vos éléments de tableau sont des tableaux eux-mêmes avec des clés de chaîne, votre meilleur pari est de définir une fonction de comparaison personnalisée. C'est assez rapide et facile à faire. Essaye ça:
Produit les éléments suivants:
la source
uasort( $inventory, function ($a, $b) { if ( $a==$b ) return 0; else return ($a > $b) ? -1 : 1; });
usort
semble plus approprié queuasort
pour trier un tableau avec des touches numériques séquentielles. Se retrouver avec un tableau où le premier élément est à l'index1
et le deuxième élément à l'index0
est un comportement étrange et un piège sûr pour les personnes qui ne sont pas familières avec les détails des tableaux de PHP;usort
vous donne la sortie que vous attendez intuitivement.Je termine sur ceci:
Appelez simplement la fonction en passant le tableau et le nom du champ du tableau de deuxième niveau. Comme:
la source
Vous pouvez utiliser
usort
avec une fonction anonyme, par exemplela source
strnatcmp
, destiné à comparer des chaînes, semble bien fonctionner ici. Apparemment, l '«ordre naturel» qu'il met en œuvre comprend le tri numérique des chaînes numériques plutôt que lexical.les sorties:
la source
De Trier un tableau de tableaux associatifs par valeur de clé donnée en php :
uasort ( http://php.net/uasort ) vous permet de trier un tableau selon votre propre fonction définie. Dans votre cas, c'est simple:
la source
cmp
fonction ici est fausse. Il est censé renvoyer "un entier inférieur, égal ou supérieur à zéro si le premier argument est considéré respectivement inférieur, égal ou supérieur au second", mais renvoie à la placetrue
oufalse
. Cela semble, remarquablement, fonctionner néanmoins - peut-être parce que l'implémentation actuelle deusort
and friends traite les cas "inférieur à" et "égal à" à l'identique - mais ne comptez pas sur le fait qu'il continue à fonctionner dans les futures versions de PHP. S'ils essaient de rendre les tris stables (c'est-à-dire de ne pas déplacer inutilement des éléments égaux), cela se cassera.usort
serait plus appropriéuasort
qu'ici, caruasort
préserve l'association entre les clés et les valeurs, ce qui est déroutant et inattendu lors de la désactivation avec un tableau numérique séquentiel. Par exemple, les index$array
ci - dessus après l'appeluasort
sont 2, 0 et 1, dans cet ordre. À moins que vous ne le souhaitiez pour une raison quelconque, vous serez probablement plus à l'aise pour utiliserusort
, ce qui réindexera le tableau ainsi que le réordonnancera.A été testé sur 100 000 enregistrements: Temps en secondes (calculé par microtime funciton). Uniquement pour les valeurs uniques sur le tri des positions clés.
Solution de la fonction de @Josh Davis: Temps passé : 1.5768740177155
Solution minière: Temps passé : 0,094044923782349
Solution:
la source
J'utilise
uasort
comme çala source
Cette fonction est réutilisable:
Il fonctionne bien sur les valeurs de chaîne par défaut, mais vous devrez subvoquer le rappel pour une fonction de comparaison de nombres si toutes vos valeurs sont des nombres.
la source
usortarr
mais appelez ensuiteuasort
au lieu deusort
; peut-être un peu déroutant. Ce dernier est - dans le cas d'un tableau séquentiel avec des index numériques, comme celui présenté dans la question - probablement ce que vous voulez réellement.Vous pouvez essayer de définir votre propre fonction de comparaison, puis utiliser usort .
la source
Voici une méthode que j'ai trouvée il y a longtemps et que j'ai un peu nettoyée. Cela fonctionne très bien et peut être rapidement modifié pour accepter également les objets.
pour changer la méthode de tri des objets, changez simplement la ligne suivante:
$tempArray[] = strtolower( $value[ $sortByKey ] );
à$tempArray[] = strtolower( $value->$sortByKey );
Pour exécuter la méthode, faites simplement
sortArray($inventory,'price','ASC');
la source
array_multisort
) ou la mienne (avecusort
) et ne semble offrir aucun avantage sur eux en échange.la source
essaye ça:
la source
Fonction dynamique complète J'ai sauté ici pour le tri associatif de tableaux et j'ai trouvé cette fonction étonnante sur http://php.net/manual/en/function.sort.php . Cette fonction est très dynamique qui trie dans l'ordre croissant et décroissant avec la clé spécifiée.
Fonction simple pour trier un tableau par une clé spécifique. Maintient l'association d'index
la source
la source
essaye ça:
pour référence voir ceci: http://php.net/manual/en/function.asort.php
voir divers drapeaux de tri ici: http://www.php.net/manual/en/function.sort.php
la source