Dada esta matriz:
$inventory = array(
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
Me gustaría ordenar $inventory
los elementos por precio para obtener:
$inventory = array(
array("type"=>"pork", "price"=>5.43),
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
);
¿Cómo puedo hacer esto?
Respuestas:
Tienes razón, la función que estás buscando es
array_multisort()
.Aquí hay un ejemplo tomado directamente del manual y adaptado a su caso:
fuente
PHP 7+
A partir de PHP 7, esto se puede hacer de manera concisa usando
usort
una función anónima que usa el operador de nave espacial para comparar elementos.Puedes hacer un tipo ascendente como este:
O un tipo descendente como este:
Para comprender cómo funciona esto, tenga en cuenta que
usort
toma una función de comparación proporcionada por el usuario que debe comportarse de la siguiente manera (de los documentos):Y tenga en cuenta también que
<=>
, el operador de la nave espacial,que es exactamente lo que
usort
necesita De hecho, casi toda la justificación dada para agregar<=>
al lenguaje en https://wiki.php.net/rfc/combined-comparison-operator es quePHP 5.3+
PHP 5.3 introdujo funciones anónimas, pero aún no tiene el operador de nave espacial. Todavía podemos usar
usort
para ordenar nuestra matriz, pero es un poco más detallado y más difícil de entender:Tenga en cuenta que, aunque es bastante común que los comparadores que tratan con valores enteros solo devuelvan la diferencia de los valores, por ejemplo
$item2['price'] - $item1['price']
, no podemos hacerlo con seguridad en este caso. Esto se debe a que los precios son números de coma flotante en el ejemplo del autor de la pregunta, pero la función de comparación a la que pasamosusort
tiene que devolver enteros parausort
que funcionen correctamente:¡Esta es una trampa importante a tener en cuenta al usar
usort
PHP 5.x! Mi versión original de esta respuesta cometió este error y, sin embargo, acumulé diez votos a favor en miles de visitas aparentemente sin que nadie se diera cuenta del error grave. La facilidad con la que los imbéciles como yo pueden arruinar las funciones de comparación es precisamente la razón por la que el operador de nave espacial más fácil de usar se agregó al lenguaje en PHP 7.fuente
uasort
. Sin embargo, después de mirar los documentos, esta respuesta sigue siendo correcta en este caso . En el ejemplo del OP, la matriz que se ordenará tiene índices numéricos secuenciales en lugar de índices de cadena, por lo queusort
es más apropiado. El usouasort
en una matriz indexada secuencialmente dará como resultado una matriz ordenada que no está ordenada por sus índices numéricos, de modo que el primer elemento visto en unforeach
bucle no$your_array[0]
lo es, lo que es poco probable que sea un comportamiento deseable.Mientras que otros han sugerido correctamente el uso de
array_multisort()
, por alguna razón, ninguna respuesta parece reconocer la existencia dearray_column()
, lo que puede simplificar enormemente la solución. Entonces mi sugerencia sería:fuente
Dado que los elementos de su matriz son matrices con teclas de cadena, su mejor opción es definir una función de comparación personalizada. Es bastante rápido y fácil de hacer. Prueba esto:
Produce lo siguiente:
fuente
uasort( $inventory, function ($a, $b) { if ( $a==$b ) return 0; else return ($a > $b) ? -1 : 1; });
usort
parece más apropiado queuasort
para ordenar una matriz con teclas numéricas secuenciales. Terminar con una matriz donde el primer elemento está en el índice1
y el segundo elemento está en el índice0
es un comportamiento extraño y una trampa segura para las personas que no están familiarizadas con los detalles de las matrices de PHP;usort
le brinda el resultado que intuitivamente esperaría.Terminé con esto:
Simplemente llame a la función, pasando la matriz y el nombre del campo de la matriz de segundo nivel. Me gusta:
fuente
Se puede usar
usort
con funciones anónimas, p. Ej.fuente
strnatcmp
, destinado a comparar cadenas, parece funcionar bien aquí. Aparentemente, el "orden natural" que implementa incluye la clasificación de cadenas numéricas numéricamente en lugar de léxico.salidas:
fuente
Desde Ordenar una matriz de matrices asociativas por valor de clave dada en php :
uasort ( http://php.net/uasort ) le permite ordenar una matriz por su propia función definida. En tu caso, eso es simple:
fuente
cmp
función aquí es incorrecta. Se supone que devuelve "un número entero menor, igual o mayor que cero si se considera que el primer argumento es respectivamente menor, igual o mayor que el segundo", pero en su lugar devuelvetrue
ofalse
. Parece, notablemente, que no obstante funciona, quizás porque la implementación actual deusort
y amigos trata los casos de "menor que" e "igual a" de manera idéntica, pero no cuente con que continúe trabajando en futuras versiones de PHP. Si intentan que los géneros sean estables (es decir, que no se muevan innecesariamente por elementos iguales), esto se romperá.usort
sería más apropiado queuasort
aquí, ya queuasort
conserva la asociación entre claves y valores que es confusa e inesperada cuando se trata de una matriz numérica secuencial. Por ejemplo, los índices de$array
arriba después de llamaruasort
son 2, 0 y 1, en ese orden. A menos que por alguna razón desee eso, probablemente se sentirá más cómodo usandousort
, lo que reindexa la matriz y la reordena.Se probó en 100 000 registros: Tiempo en segundos (calculado por microtiempo de función). Solo para valores únicos en la clasificación de posiciones clave.
Solución de la función de @Josh Davis: Tiempo invertido: 1.5768740177155
Solución minera : Tiempo invertido: 0.094044923782349
Solución:
fuente
Yo uso
uasort
asifuente
Esta función es reutilizable:
Funciona bien en los valores de cadena de forma predeterminada, pero tendrá que sustituir la devolución de llamada para una función de comparación de números si todos sus valores son números.
fuente
usortarr
pero luego llamas enuasort
lugar deusort
; quizás un poco confuso. El último es, en el caso de una matriz secuencial con índices numéricos, como el que se muestra en la pregunta, probablemente lo que realmente desea.Puede intentar definir su propia función de comparación y luego usar usort .
fuente
Aquí hay un método que encontré hace mucho tiempo y lo limpié un poco. Esto funciona muy bien y se puede cambiar rápidamente para aceptar objetos también.
para cambiar el método para ordenar objetos simplemente cambie la siguiente línea:
$tempArray[] = strtolower( $value[ $sortByKey ] );
a$tempArray[] = strtolower( $value->$sortByKey );
Para ejecutar el método simplemente haz
sortArray($inventory,'price','ASC');
fuente
array_multisort
) o la mía (conusort
) y, a cambio, parece no ofrecer ventajas sobre ellos.fuente
prueba esto:
fuente
Función dinámica completa Salté aquí para la ordenación asociativa de matrices y encontré esta increíble función en http://php.net/manual/en/function.sort.php . Esta función es muy dinámica y se ordena en orden ascendente y descendente con la tecla especificada.
Función simple para ordenar una matriz por una clave específica. Mantiene asociación de índice
fuente
fuente
prueba esto:
para referencia vea esto: http://php.net/manual/en/function.asort.php
ver varios indicadores de clasificación aquí: http://www.php.net/manual/en/function.sort.php
fuente