Saltar al contenido

¿Cómo puedo ordenar matrices y datos en PHP?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *