Basta ya de indagar en otras páginas porque llegaste al sitio adecuado, contamos con la respuesta que buscas pero sin complicaciones.
Solución:
Matrices unidimensionales básicas
$array = array(3, 5, 2, 8);
Funciones de clasificación aplicables:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
La diferencia entre ellos es simplemente si se mantienen las asociaciones clave-valor (el “a
“funciones), ya sea de menor a mayor o inversa (“r
“), ya sea que ordene 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.
Matrices multidimensionales, incluidas matrices de objetos
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
Si quieres ordenar $array
por la tecla ‘foo’ de cada entrada, necesita un función de comparación personalizada. Lo anterior sort
y las funciones relacionadas funcionan con valores simples que saben comparar y clasificar. PHP no simplemente “sabe” qué hacer con un valor complejo igual que array('foo' => 'bar', 'baz' => 42)
aunque; así que tienes que contarlo.
Para hacer eso, necesita crear un función de comparación. Esa función toma dos elementos y debe regresar 0
si estos elementos se consideran iguales, un valor inferior a 0
si el primer valor es menor y un valor mayor que 0
si el primer valor es mayor. Eso es todo lo que se necesita:
function cmp(array $a, array $b)
if ($a['foo'] < $b['foo'])
return -1;
else if ($a['foo'] > $b['foo'])
return 1;
else
return 0;
A menudo, querrá utilizar una función anónima como devolución de llamada. Si desea utilizar un método o un método estático, consulte las otras formas de especificar una devolución de llamada en PHP.
Luego usa una de estas funciones:
usort
uasort
uksort
Nuevamente, solo se diferencian en si mantienen asociaciones clave-valor y clasifican por valores o claves. Lea su documentación para obtener más detalles.
Uso de ejemplo:
usort($array, 'cmp');
usort
tomará dos elementos de la matriz y llamará a su cmp
Funcionar con ellos. Entonces cmp()
será llamado con $a
como array('foo' => 'bar', 'baz' => 42)
y $b
como otro array('foo' => ..., 'baz' => ...)
. La función luego vuelve a usort
cuál de los valores era mayor o si eran iguales. usort
repite este proceso pasando diferentes valores para $a
y $b
hasta que se ordene la matriz. los cmp
la función se llamará muchas veces, por lo menos tantas veces como valores haya en $array
, con diferentes combinaciones de valores para $a
y $b
cada vez.
Para acostumbrarse a esta idea, intente esto:
function cmp($a, $b)
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
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 con cualquier valor, los valores no tienen que ser matrices complejas. Si tiene una comparación personalizada que desea hacer, 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 ordena en su lugar, no es necesario asignar el valor de retorno a nada. $array = sort($array)
reemplazará la matriz con true
, no con una matriz ordenada. Solo sort($array);
obras.
Comparaciones numéricas personalizadas
Si desea ordenar por baz
clave, que es numérica, todo lo que necesita hacer es:
function cmp(array $a, array $b)
return $a['baz'] - $b['baz'];
Gracias a EL PODER DE LAS MATEMÁTICAS esto devuelve un valor < 0, 0 or > 0 dependiendo de si $a
es menor, igual o mayor que $b
.
Tenga en cuenta que esto no funcionará bien para float
valores, ya que se reducirán a un int
y perder precisión. Usar explícito -1
, 0
y 1
devuelve valores en su lugar.
Objetos
Si tiene una matriz de objetos, funciona de la misma manera:
function cmp($a, $b)
return $a->baz - $b->baz;
Funciones
Puede hacer todo lo que necesite dentro de una función de comparación, incluidas funciones de llamada:
function cmp(array $a, array $b)
return someFunction($a['baz']) - someFunction($b['baz']);
Instrumentos de cuerda
Un atajo para la primera versión de comparación de cadenas:
function cmp(array $a, array $b)
return strcmp($a['foo'], $b['foo']);
strcmp
hace exactamente lo que se espera de cmp
aquí vuelve -1
, 0
o 1
.
Operador de nave espacial
PHP 7 introdujo el operador de nave espacial, que unifica y simplifica las comparaciones de igual / menor / mayor que entre tipos:
function cmp(array $a, array $b)
return $a['foo'] <=> $b['foo'];
Ordenar por múltiples campos
Si desea ordenar principalmente por foo
, pero si foo
es igual para dos elementos ordenados por baz
:
function cmp(array $a, array $b)
if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0)
return $cmp;
else
return $a['baz'] - $b['baz'];
Para aquellos familiarizados, esto es equivalente a una consulta SQL con ORDER BY foo, baz
.
Vea también esta versión abreviada muy ordenada y cómo crear una función de comparación de este tipo de forma dinámica para un número arbitrario de claves.
Clasificación en un orden estático manual
Si desea ordenar los elementos en un “orden manual” como “foo”, “bar”, “baz”:
function cmp(array $a, array $b)
static $order = array('foo', 'bar', 'baz');
return array_search($a['foo'], $order) - array_search($b['foo'], $order);
Por todo lo anterior, si está usando PHP 5.3 o superior (y realmente debería), use funciones anónimas para código más corto y para evitar tener otra función global flotando alrededor:
usort($array, function (array $a, array $b) return $a['baz'] - $b['baz']; );
Así de simple puede ser ordenar una matriz multidimensional compleja. Una vez más, piense en términos de enseñar a PHP cómo saber cuál de dos elementos es “mayor”; deje que PHP haga la clasificación real.
También para todo lo anterior, para cambiar entre orden ascendente y descendente, simplemente cambie el $a
y $b
discusiones alrededor. P.ej:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
Ordenar una matriz basada en otra
Y luego está lo peculiar array_multisort
, que le permite ordenar una matriz en función de otra:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
El resultado esperado aquí sería:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Usar array_multisort
para llegar allí:
array_multisort($array1, $array2);
A partir de PHP 5.5.0 puede utilizar array_column
para extraer una columna de una matriz multidimensional y ordenar la matriz en esa columna:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
También puede ordenar en más de una columna en cada dirección:
array_multisort(array_column($array, 'foo'), SORT_DESC,
array_column($array, 'bar'), SORT_ASC,
$array);
A partir de PHP 7.0.0 también puede extraer propiedades de una matriz de objetos.
Si tiene casos más comunes, no dude en editar esta respuesta.
Bueno, la mayoría de los métodos básicos ya están cubiertos por deceze, trataría de ver otros tipos de tipos
Clasificación con SPL
SplHeap
class SimpleHeapSort extends SplHeap
public function compare($a, $b)
return strcmp($a, $b);
// Let's populate our heap here (data of 2009)
$heap = new SimpleHeapSort();
$heap->insert("a");
$heap->insert("b");
$heap->insert("c");
echo implode(PHP_EOL, iterator_to_array($heap));
Producción
c
b
a
SplMaxHeap
La clase SplMaxHeap proporciona las principales funcionalidades de un montón, manteniendo el máximo en la parte superior.
$heap = new SplMaxHeap();
$heap->insert(1);
$heap->insert(2);
$heap->insert(3);
SplMinHeap
La clase SplMinHeap proporciona las principales funcionalidades de un montón, manteniendo el mínimo en la parte superior.
$heap = new SplMinHeap ();
$heap->insert(3);
$heap->insert(1);
$heap->insert(2);
Otros tipos de género
Ordenamiento de burbuja
Del artículo de Wikipedia sobre clasificación de burbujas:
La clasificación de burbujas, a veces denominada incorrectamente como clasificación de hundimiento, es un algoritmo de clasificación simple que funciona recorriendo repetidamente la lista para clasificar, comparando cada par de elementos adyacentes e intercambiándolos si están en el orden incorrecto. El paso a través de la lista se repite hasta que no se necesitan intercambios, lo que indica que la lista está ordenada. El algoritmo recibe su nombre de la forma en que los elementos más pequeños “burbujean” en la parte superior de la lista. Debido a que solo usa comparaciones para operar con elementos, es un tipo de comparación. Aunque el algoritmo es simple, la mayoría de los otros algoritmos de clasificación son más eficientes para listas grandes.
function bubbleSort(array $array)
$array_size = count($array);
for($i = 0; $i < $array_size; $i ++)
for($j = 0; $j < $array_size; $j ++)
if ($array[$i] < $array[$j])
$tem = $array[$i];
$array[$i] = $array[$j];
$array[$j] = $tem;
return $array;
Orden de selección
Del artículo de Wikipedia sobre ordenación por selección:
En informática, la clasificación por selección es un algoritmo de clasificación, específicamente una clasificación por comparación in situ. Tiene una complejidad de tiempo O (n2), lo que lo hace ineficaz en listas grandes y, en general, funciona peor que el tipo de inserción similar. El ordenamiento por selección se destaca por su simplicidad y tiene ventajas de rendimiento sobre algoritmos más complicados en ciertas situaciones, particularmente cuando la memoria auxiliar es limitada.
function selectionSort(array $array)
$length = count($array);
for($i = 0; $i < $length; $i ++)
$min = $i;
for($j = $i + 1; $j < $length; $j ++)
if ($array[$j] < $array[$min])
$min = $j;
$tmp = $array[$min];
$array[$min] = $array[$i];
$array[$i] = $tmp;
return $array;
Tipo de inserción
Del artículo de Wikipedia sobre ordenación por inserción:
La ordenación por inserción es un algoritmo de ordenación simple que crea la matriz (o lista) ordenada final un elemento a la vez. Es mucho menos eficiente en listas grandes que los algoritmos más avanzados como el ordenamiento rápido, el ordenamiento en pila o el ordenamiento combinado. Sin embargo, la ordenación por inserción ofrece varias ventajas:
function insertionSort(array $array)
$count = count($array);
for($i = 1; $i < $count; $i ++)
$j = $i - 1;
// second element of the array
$element = $array[$i];
while ( $j >= 0 && $array[$j] > $element )
$array[$j + 1] = $array[$j];
$array[$j] = $element;
$j = $j - 1;
return $array;
Shellsort
Del artículo de Wikipedia sobre Shellsort:
Shellsort, también conocido como clasificación de Shell o método de Shell, es una clasificación de comparación in situ. Generaliza una ordenación de intercambio, como inserción o ordenación de burbujas, iniciando la comparación e intercambio de elementos con elementos que están muy separados antes de terminar con elementos vecinos.
function shellSort(array $array)
$gaps = array(
1,
2,
3,
4,
6
);
$gap = array_pop($gaps);
$length = count($array);
while ( $gap > 0 )
for($i = $gap; $i < $length; $i ++)
$tmp = $array[$i];
$j = $i;
while ( $j >= $gap && $array[$j - $gap] > $tmp )
$array[$j] = $array[$j - $gap];
$j -= $gap;
$array[$j] = $tmp;
$gap = array_pop($gaps);
return $array;
Tipo de peine
Del artículo de Wikipedia sobre clasificación de peine:
La clasificación por peine es un algoritmo de clasificación relativamente simple originalmente diseñado por Wlodzimierz Dobosiewicz en 1980. Posteriormente fue redescubierto por Stephen Lacey y Richard Box en 1991. La clasificación por peine mejora la clasificación por burbujas.
function combSort(array $array)
$gap = count($array);
$swap = true;
while ( $gap > 1
Combinar ordenación
Del artículo de Wikipedia sobre ordenación por combinación:
En ciencias de la computación, una ordenación por combinación (también deletreada comúnmente mergesort) es un algoritmo de ordenación basado en comparaciones O (n log n). La mayoría de las implementaciones producen una ordenación estable, lo que significa que la implementación conserva el orden de entrada de elementos iguales en la salida ordenada.
function mergeSort(array $array)
if (count($array) <= 1)
return $array;
$left = mergeSort(array_splice($array, floor(count($array) / 2)));
$right = mergeSort($array);
$result = array();
while ( count($left) > 0 && count($right) > 0 )
if ($left[0] <= $right[0])
array_push($result, array_shift($left));
else
array_push($result, array_shift($right));
while ( count($left) > 0 )
array_push($result, array_shift($left));
while ( count($right) > 0 )
array_push($result, array_shift($right));
return $result;
Ordenación rápida
Del artículo de Wikipedia sobre Quicksort:
Clasificación rápida, o clasificación de intercambio de particiones, es un algoritmo de clasificación desarrollado por Tony Hoare que, en promedio, hace comparaciones O (n log n) para clasificar n elementos. En el peor de los casos, hace comparaciones O (n2), aunque este comportamiento es raro.
function quickSort(array $array)
if (count($array) == 0)
return $array;
$pivot = $array[0];
$left = $right = array();
for($i = 1; $i < count($array); $i ++)
if ($array[$i] < $pivot)
$left[] = $array[$i];
else
$right[] = $array[$i];
return array_merge(quickSort($left), array(
$pivot
), quickSort($right));
Tipo de permutación
Del artículo de Wikipedia sobre ordenación por permutación:
Orden de permutación, que procede generando las posibles permutaciones de la matriz / lista de entrada hasta descubrir la ordenada.
function permutationSort($items, $perms = array())
if (empty($items))
if (inOrder($perms))
return $perms;
else
for($i = count($items) - 1; $i >= 0; -- $i)
$newitems = $items;
$newperms = $perms;
list($foo) = array_splice($newitems, $i, 1);
array_unshift($newperms, $foo);
$res = permutationSort($newitems, $newperms);
if ($res)
return $res;
function inOrder($array)
for($i = 0; $i < count($array); $i ++)
if (isset($array[$i + 1]))
if ($array[$i] > $array[$i + 1])
return False;
return True;
Orden de radix
Del artículo de Wikipedia sobre la clasificación de Radix:
En informática, la ordenación por base es un algoritmo de ordenación de enteros no comparativo que ordena los datos con claves enteras agrupando las claves por dígitos individuales que comparten la misma posición y valor significativos.
// Radix Sort for 0 to 256
function radixSort($array)
$n = count($array);
$partition = array();
for($slot = 0; $slot < 256; ++ $slot)
$partition[] = array();
for($i = 0; $i < $n; ++ $i)
$partition[$array[$i]->age & 0xFF][] = &$array[$i];
$i = 0;
for($slot = 0; $slot < 256; ++ $slot)
for($j = 0, $n = count($partition[$slot]); $j < $n; ++ $j)
$array[$i ++] = &$partition[$slot][$j];
return $array;
Tipo estable
Digamos que tiene una matriz como esta:
['Kale', 'Kaleidoscope', 'Aardvark', 'Apple', 'Leicester', 'Lovely']
Y ahora desea ordenar solo por la primera letra:
usort($array, function($a, $b)
return strcmp($a[0], $b[0]);
);
El resultado es este:
['Apple', 'Aardvark', 'Kale', 'Kaleidoscope', 'Lovely', 'Leicester']
¡El tipo no era estable!
El observador entusiasta puede haber notado que el algoritmo de ordenación de matrices (QuickSort) no produjo un resultado estable y que no se conservó el orden original entre las palabras de la misma primera letra. 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 ordenamientos consecutivos en diferentes campos que no deberían cancelar el trabajo del otro.
La transformación de Schwartzian
La transformada de Schwartz, también conocida como el modismo decorar-ordenar-no decorar, produce una ordenación estable con un algoritmo de ordenación inherentemente inestable.
Primero, decoras cada elemento de la matriz con otra matriz que comprende una clave primaria (el valor) y una clave secundaria (su índice o posición):
array_walk($array, function(&$element, $index)
$element = array($element, $index); // decorate
);
Esto transforma la matriz en esto:
[
['Kale', 0], ['Kaleidoscope', 1],
['Aardvark', 2], ['Apple', 3],
['Leicester', 4], ['Lovely', 5]
]
Ahora, ajustamos el paso de comparación; comparamos la primera letra nuevamente, pero si son iguales, la clave secundaria se usa para mantener el orden original:
usort($array, function($a, $b)
// $a[0] and $b[0] contain the primary sort key
// $a[1] and $b[1] contain the secondary sort key
$tmp = strcmp($a[0][0], $b[0][0]);
if ($tmp != 0)
return $tmp; // use primary key comparison results
return $a[1] - $b[1]; // use secondary key
);
Posteriormente, desdecoramos:
array_walk($array, function(&$element)
$element = $element[0];
);
El resultado final:
['Aardvark', 'Apple', 'Kale', 'Kaleidoscope', 'Leicester', 'Lovely']
¿Qué pasa con la reutilización?
Tuvo que reescribir su función de comparación para trabajar con los elementos transformados de la matriz; 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:
function stablecmp($fn)
return function($a, $b) use ($fn)
if (($tmp = call_user_func($fn, $a[0], $b[0])) != 0)
return $tmp;
else
return $a[1] - $b[1];
;
Escribamos el paso de clasificación usando esta función:
usort($array, stablecmp(function($a, $b)
return strcmp($a[0], $b[0]);
));
¡Voila! Vuelve tu código de comparación impecable.
Tienes la opción de añadir valor a nuestro contenido dando tu veteranía en las explicaciones.