Cómo ordenar un array multidimensional en PHP

La estructura de datos más utilizada en PHP es, por lejos, el arreglo.

Esto se debe a que la implementación de ellos es extremadamente flexible.

Un problema común que nos encontramos es el ordenarlos.

Cuando los arreglos son de una única dimensión no hay mucho problema, basta una función como sort, pero cuando el arreglo es una matriz las cosas son un poco más complejas ya que pueden existir diferentes criterios de ordenamiento.

Por ejemplo, si tu arreglo se ve así:

[
 [
   'name' => 'Juan',
  'age' => 40,
 ],
   'name' => 'Alberto',
   'age' => 60,
 ],
]

El resultado será diferente si queremos ordenar por age que por name

Claro que podrías usar una solución diseñada por tí mismo basada en un par de ciclos anidados y seguramente funcionaría, pero sería trabajar de más.

Ordenar un arreglo PHP según un criterio propio

Una función muy útil para resolver este tipo de situación es usort.

Esta función recibe un arreglo como parámetro y una función que se utiliza para comparar cualquier par de elementos entre sí (Lo que se conoce como un callback).

De este modo, para el ejemplo anterior podríamos definir dos funciones de comparación:

  1. Por nombre
  2. Por edad
function compareByName(array $elem1, array $elem2) {
    if ( $elem1['name'] > $elem2['name'] ) {
          return 1;
    } elseif ( $elem1['name'] < $elem2['name'] ) {
          return -1;
    } else {
          return 0;
    }
}

function compareByAge(array $elem1, array $elem2) {
    if ( $elem1['age'] > $elem2['age'] ) {
          return 1;
    } elseif ( $elem1['age'] < $elem2['age'] ) {
          return -1;
    } else {
          return 0;
    }
}

Cualquiera de estas podría ser utilizada, según el criterio que necesites, por ejemplo:

usort($people, 'compareByName');

O podríamos usar también una función anónima:

usort($people, function( array $elem1, $elem2 ) {
    if ( $elem1['age'] > $elem2['age'] ) {
          return 1;
    } elseif ( $elem1['age'] < $elem2['age'] ) {
          return -1;
    } else {
          return 0;
    }
});

O, si estás usando php7 o superior:

usort($people, function( array $elem1, $elem2 ) {
    return $elem1['name'] <=> $elem2['name'];
});

mchojrin

Por mchojrin

Ayudo a desarrolladores PHP a acceder mercados y clientes más sofisticados y exigentes

4 comentarios

  1. COMO HAGO PARA ORDENAR SUB – NAME – ID {
    «id»: 24366,
    «name»: «Comodidad y Descanso»,
    «sub»: {
    «id»: 24367,
    «name»: «Almohadas con memory foam»
    }
    }

    1. Hola Luis:

      No estoy seguro de comprender tu pregunta correctamente pero en todo caso, la clave siempre radica en la definición de tu función de comparación.

      La pregunta que debes responder en definitiva es cómo determinar que un «sub» es mayor, menor o igual que otro y, en base a eso crear tu función.

      Si quieres publica una versión de tu código de comparación y la analizamos.

      Saludos!

  2. Como se podría ordenar por un segundo criterio por ejemplo supongamos que queremos ordenar por edad, pero en un dado caso que ambas edades sean iguales se ordene por el nombre. Ejemplo:
    Juan 20
    Mario 21
    Raúl 25
    Cesar 27
    Samuel 27
    Walmaro 27
    Rodrigo 30

    Como podemos ver César, Samuel y walmaro tienen la misma edad pero entre ellos tres se ordenó alfabéticamente primero César, luego samuel y por último walmaro

    1. Hola Ricardo:

      La clave está en la definición de la función de comparación. Lo que deberías hacer es crear un criterio mixto de esta forma:

      usort($people, function( array $elem1, $elem2 ) {
      if ( $elem1['age'] > $elem2['age'] ) {
      return 1;
      } elseif ( $elem1['age'] < $elem2['age'] ) {
      return -1;
      } else {
      if ( $elem1['name'] > $elem2['name') ) {
      return 1;
      } elseif ( $elem1['name'] < $elem2['name') ) {
      return -1;
      } else {
      return 0;
      }
      }
      });

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.