Esta pregunta pretende ser una referencia para preguntas sobre la ordenación de matrices en PHP. Es fácil pensar que su caso particular es único y merece una nueva pregunta, pero la mayoría son variaciones menores de una de las soluciones en esta página.
Si su pregunta se cierra como un duplicado de esta, solicite que se vuelva a abrir su pregunta solo si puede explicar por qué difiere notablemente de todo lo que se muestra a continuación.
¿Cómo clasifico una matriz en PHP?
¿Cómo clasifico una matriz compleja en PHP?
¿Cómo clasifico una matriz de objetos en PHP?
Para la respuesta práctica usando las funciones existentes de PHP, ver 1., para la respuesta académica detallada sobre algoritmos de clasificación (qué funciones de PHP implementan y cuáles puede necesitar para casos realmente, muy complejos), consulte 2.
Respuestas:
Arreglos unidimensionales básicos
Funciones de clasificación aplicables:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
La diferencia entre estos es simplemente si las asociaciones de valores clave se mantienen (el "
a
" funciones), si ordena de bajo a alto o inverso ("r
"), si clasifica valores o claves ("k
") y cómo compara los valores ("nat
" vs. normal). Consulte http://php.net/manual/en/array.sorting.php para obtener una descripción general y enlaces a más detalles.Conjuntos multidimensionales, incluidos conjuntos de objetos
Si desea ordenar
$array
por la clave 'foo' de cada entrada, necesita un función de comparación personalizada . Lassort
funciones anteriores y relacionadas funcionan con valores simples que saben cómo comparar y ordenar. PHP no simplemente "sabe" qué hacer con un valor complejo como elarray('foo' => 'bar', 'baz' => 42)
embargo; así que necesitas contarlo.Para hacer eso, necesita crear una función de comparación . Esa función toma dos elementos y debe regresar
0
si estos elementos se consideran iguales, un valor inferior a0
si el primer valor es menor y un valor mayor que0
si el primer valor es mayor. Eso es todo lo que se necesita:A menudo, querrás usar un función anónima como devolución de llamada. Si desea utilizar un método o método estático, consulte el otras formas de especificar una devolución de llamada en PHP .
Luego usa una de estas funciones:
usort
uasort
uksort
Una vez más, solo difieren en si mantienen asociaciones clave-valor y clasifican por valores o claves. Lea su documentación para más detalles.
Ejemplo de uso:
usort
tomará dos elementos de la matriz y llamará a sucmp
función con ellos. Entoncescmp()
se llamará con$a
asarray('foo' => 'bar', 'baz' => 42)
y$b
como otroarray('foo' => ..., 'baz' => ...)
. La función luego regresa ausort
cuál de los valores era mayor o si eran iguales.usort
repite este proceso pasando valores diferentes para$a
y$b
hasta que se ordena la matriz. Lacmp
función se llamará muchas veces, al menos tantas veces como haya valores$array
, con diferentes combinaciones de valores para$a
y$b
cada vez.Para acostumbrarse a esta idea, intente esto:
Todo lo que hizo fue definir una forma personalizada de comparar dos elementos, eso es todo lo que necesita. Eso funciona con todo tipo de valores.
Por cierto, esto funciona en cualquier valor, los valores no tienen que ser matrices complejas. Si desea hacer una comparación personalizada, también puede hacerlo en una simple matriz de números.
sort
¡ordena por referencia y no devuelve nada útil!Tenga en cuenta que la matriz se ordena en su lugar , no necesita asignar el valor de retorno a nada.
$array = sort($array)
reemplazará la matriz contrue
, no con una matriz ordenada. Solosort($array);
funcionaComparaciones numéricas personalizadas
Si desea ordenar por la
baz
clave, que es numérica, todo lo que necesita hacer es:Gracias a The PoWEr of MATH esto devuelve un valor <0, 0 o> 0 dependiendo de si
$a
es menor, igual o mayor que$b
.Tenga en cuenta que esto no funcionará bien para los
float
valores, ya que se reducirán a unaint
y perderán precisión. Utilice explícita-1
,0
y1
los valores de retorno en su lugar.Objetos
Si tiene una matriz de objetos, funciona de la misma manera:
Las funciones
Puede hacer cualquier cosa que necesite dentro de una función de comparación, incluidas las funciones de llamada:
Instrumentos de cuerda
Un atajo para la primera versión de comparación de cadenas:
strcmp
hace exactamente lo que se espera decmp
aquí, vuelve-1
,0
o1
.Operador de nave espacial
PHP 7 introdujo el operador de nave espacial , que unifica y simplifica igual / menor / mayor que las comparaciones entre tipos:
Ordenar por múltiples campos
Si desea ordenar principalmente por
foo
, pero sifoo
es igual para dos elementos, ordene porbaz
:Para aquellos familiares, esto es equivalente a una consulta SQL con
ORDER BY foo, baz
.También vea esta versión abreviada muy ordenada y cómo crear una función de comparación de este tipo dinámicamente para un número arbitrario de teclas .
Ordenar en un orden manual, estático
Si desea ordenar los elementos en un "orden manual" como "foo", "bar", "baz" :
Por todo lo anterior, si está utilizando PHP 5.3 o superior (y realmente debería hacerlo), use funciones anónimas para un código más corto y para evitar tener otra función global flotando:
Así de simple puede ser ordenar una compleja matriz multidimensional. Nuevamente, solo piense en términos de enseñar a PHP cómo saber cuál de los dos elementos es "mayor" ; deja que PHP haga la clasificación real.
También para todo lo anterior, para cambiar entre orden ascendente y descendente, simplemente cambie los argumentos
$a
y$b
. P.ej:Ordenar una matriz basada en otra
Y luego está lo peculiar
array_multisort
, que le permite ordenar una matriz basada en otra:El resultado esperado aquí sería:
Use
array_multisort
para llegar allí:A partir de PHP 5.5.0, puede usar
array_column
para extraer una columna de una matriz multidimensional y ordenar la matriz en esa columna:A partir de PHP 7.0.0, también puede extraer propiedades de una matriz de objetos.
fuente
array_flip()
hacer uso de una búsqueda de posición más rápida, por ejemplo, en$order[$a['foo']]
lugar dearray_search($a['foo'], $order)
.Bueno, la mayoría de los métodos básicos ya están cubiertos por el engaño . Intentaría ver otros tipos de
Ordenar con SPL
SplHeap
Salida
SplMaxHeap
La clase SplMaxHeap proporciona las principales funcionalidades de un montón, manteniendo el máximo en la parte superior.
SplMinHeap
Otros tipos de ordenación
Ordenamiento de burbuja
Del artículo de Wikipedia sobre Bubble Sort:
Tipo de selección
Del artículo de Wikipedia sobre el tipo de selección:
Tipo de inserción
Del artículo de Wikipedia sobre el tipo de inserción:
Shellsort
Del artículo de Wikipedia sobre Shellsort:
Tipo de peine
Del artículo de Wikipedia sobre el tipo de peine:
Ordenar fusión
Del artículo de Wikipedia sobre Merge sort:
Ordenación rápida
Del artículo de Wikipedia sobre Quicksort:
Tipo de permutación
Del artículo de Wikipedia sobre el tipo de permutación:
Tipo Radix
Del artículo de Wikipedia sobre el tipo Radix:
fuente
O(n^2)
comparaciones si usamos solo el primer elemento como pivote)Tipo estable
Digamos que tiene una matriz como esta:
Y ahora quieres ordenar solo en la primera letra:
El resultado es este:
¡El tipo no era estable!
El observador entusiasta puede haber notado que el algoritmo de clasificación de matriz (QuickSort) no produjo un resultado estable y que el orden original entre las palabras de la misma primera letra no se conservó. Este caso es trivial y deberíamos haber comparado toda la cadena, pero supongamos que su caso de uso es más complicado, como dos tipos consecutivos en diferentes campos que no deberían cancelar el trabajo del otro.
La transformación de Schwartz
La transformación de Schwartz , también conocida como modismo decorar-ordenar-decorar, produce un ordenamiento estable con un algoritmo de ordenamiento inherentemente inestable.
Primero, decora cada elemento de matriz con otra matriz que comprende una clave primaria (el valor) y una clave secundaria (su índice o posición):
Esto transforma la matriz en esto:
Ahora, ajustamos el paso de comparación; volvemos a comparar la primera letra, pero si son iguales, la clave secundaria se utiliza para conservar el orden original:
Luego, decoramos:
El resultado final:
¿Qué pasa con la reutilización?
Debía reescribir su función de comparación para trabajar con los elementos de la matriz transformada; es posible que no desee editar sus delicadas funciones de comparación, así que aquí hay un contenedor para la función de comparación:
Escribamos el paso de clasificación usando esta función:
Voila! Su código de comparación impecable está de vuelta.
fuente
A partir de PHP 5.3 con cierres, también es posible usar un cierre para determinar el orden de su clasificación.
Por ejemplo, suponiendo que $ array es una matriz de objetos que contienen una propiedad de mes.
fuente
LINQ
En .NET, LINQ se usa con frecuencia para ordenar, lo que proporciona una sintaxis mucho mejor que las funciones de comparación, especialmente cuando los objetos necesitan ser ordenados por múltiples campos. Hay varios puertos de LINQ to PHP, incluida la biblioteca YaLinqo *. Con él, las matrices se pueden ordenar con una sola línea sin escribir funciones de comparación complejas.
Las comparaciones se pueden personalizar aún más al pasar una devolución de llamada como un segundo argumento, por ejemplo:
Aquí,
'$v->count'
es una forma abreviada defunction ($v) { return $v->count; }
(cualquiera puede ser usado). Estas cadenas de métodos devuelven iteradores, los iteradores se pueden transformar en matrices agregando->toArray()
al final si es necesario.Internamente,
orderBy
y métodos relacionados con la llamada funciones de clasificación de matriz adecuados (uasort
,krsort
,multisort
,usort
etc.).LINQ contiene muchos más métodos inspirados en SQL: filtrado, agrupación, unión, agregación, etc. Es el más adecuado para los casos en que se deben realizar transformaciones complejas en matrices y objetos sin depender de bases de datos.
* desarrollado por mí, vea el archivo Léame para más detalles y comparación con otros puertos LINQ
fuente
Clasificación multidimensional por valor clave
Tipo natural de una matriz multidimensional por un valor clave y también mantener el orden original (no mezclar las teclas principales):
Caso de prueba:
fuente
Es muy conveniente ordenar matrices con función ordenada de Nspl :
Clasificación básica
Ordenar por resultado de función
Ordenar una matriz multidimensional
Ordenar una matriz de objetos
Ordenar con una función de comparación
Puedes ver todos estos ejemplos aquí .
fuente
Si desea ordenar por el valor clave, puede hacerlo una línea, elegante y clara. Esto ordenará por el precio ascendente. Utiliza array_multisort y array_column.
para producir
fuente
Esta página es muy completa, pero quiero agregar un poco más sobre la increíble utilidad del operador de la nave espacial (operador de comparación de tres vías), un hermoso hijo de PHP7 +.
Usando el operador de la nave espacial para implementar múltiples condiciones de clasificación
Esto da grandes pasos para reducir la hinchazón de código y mejorar la legibilidad.
Al escribir su función de clasificación personalizada (
usort()
/uasort()
/uksort()
) para procesar múltiples condiciones, solo necesita escribir matrices balanceadas a cada lado del operador y devolver el resultado. No más bloques de condiciones anidadas o retornos múltiples.Los elementos de ambos lados del operador se desplazarán de izquierda a derecha, uno a la vez, y se devolverá la evaluación tan pronto como se encuentre un empate o cuando se hayan comparado todos los elementos.
Datos de muestra para mis demostraciones:
Demostraciones (para evitar la hinchazón de página de Stackoverflow, consulte el enlace de demostración para las salidas):
Lógica de clasificación:
flotador ASC
Lógica de clasificación:
ASC booleana
Lógica de clasificación:
natString ASC
Esta sintaxis le permite ordenar valores, resultados funcionales, datos anidados profundamente y ordenar la dirección de una manera elegante. Definitivamente vale la pena ponerlo en su cinturón de herramientas de php ... para casos en los que está procesando datos que no son de base de datos, porque, por supuesto, SQL sería una técnica mucho más sensata.
A su discreción, desde PHP7.4 puede usar la sintaxis de flecha con estas funciones anónimas. El mismo guión con sintaxis de flecha .
fuente
Si alguien quiere una solución más simple para manipular matrices, simplemente use el paquete Laravel Collection, que tiene una función sortBy implementada que le permite ordenar por teclas simplemente.
es decir, para ordenar primero por a, luego b, luego c, la cláusula correcta sería
https://packagist.org/packages/tightenco/collect
fuente
Hay varias formas de ordenar una matriz. Mencionaré algunos métodos para hacer esa tarea. En primer lugar, daré una matriz entera que se llama como '$ números'.
Esta es la forma normal de crear una matriz. Supongamos que quiero ordenar esa matriz en orden ascendente. Para eso, se puede usar el método 'sort ()'.
Ahora considere la salida de eso,
Puede ver que la matriz de números impresos está ordenada. Si desea que esa matriz de números se ordene en orden descendente, puede usar el método 'rsort ()' para esa tarea.
considere la salida ..
Ahora la matriz está ordenada en orden descendente. Bien, consideremos una matriz asociativa. Daré una matriz asociativa (matriz asociativa significa que, una matriz cuyo índice tiene un valor clave único) como este,
Entonces, ahora quiero ordenar esta matriz en orden ascendente según su valor. El método'asort () 'se puede usar para eso.
Si ordena el orden descendente según su valor, se puede usar el método 'arsort ()'. Suponga que desea ordenar esa matriz según su valor clave. En esto, se puede usar el método 'ksort ()'.
Ahora considere la salida.
Ahora la matriz se ordena según su valor clave. Si desea ordenar la matriz en orden descendente según su valor clave, se puede utilizar el método 'krsort ()'.
Ahora la matriz asociativa se ordena en orden descendente según su valor clave. Mire la salida.
Estos son algunos de los métodos para ordenar una matriz en orden ascendente o descendente en php. Espero que puedas tener una idea. ¡Gracias!
fuente
Lo más simple es usar la función usort para ordenar la matriz sin ningún bucle: a continuación se muestra un ejemplo:
Esto se ordenará en orden descendente:
Esto se ordenará en orden de finalización:
fuente