La magia de la ordenación: cómo PHP ordena arrays bidimensionales
\n\nImagínese: tiene una tabla con datos — una lista de usuarios, productos o pedidos. Necesita ordenarla por edad, precio o fecha. En Excel, esto se hace con un clic. ¿Y en PHP? Aquí comienza lo interesante. La pregunta "Sort a 2d array by a column value" en Stack Overflow ha acumulado miles de visitas no por casualidad — es una de esas tareas que todo desarrollador enfrenta.
\n\nHoy no solo le daremos código listo. Nos meteremos "bajo el capó" de PHP y entenderemos cómo funcionan realmente los mecanismos de ordenación de un array multidimensional. Aprenderá por qué usort es más rápido que los bucles, cómo PHP compara elementos y qué trampas esperan al principiante. ¡Allá vamos!
El problema: ¿por qué ordenar un array 2D no es trivial?
\n\nEn PHP existen sort() y asort() para arrays unidimensionales. Pero cuando el array se vuelve bidimensional (array de arrays), las funciones estándar fallan. ¿Por qué? Porque PHP no sabe por qué "columna" (clave del array interno) desea ordenar.
Aquí hay un ejemplo típico:
\n\n<?php\n$users = [\n ['name' => 'Анна', 'age' => 25],\n ['name' => 'Иван', 'age' => 30],\n ['name' => 'Мария', 'age' => 22]\n];\n// ¿Cómo ordenar por edad?\n?>\n\n¿Simplemente llamar a sort($users)? No — PHP mostrará una advertencia y hará algo incorrecto. Se necesita un enfoque más inteligente.
Solución n.º 1: El clásico usort con función personalizada
\n\nLa forma más popular es usar usort(). Esta función acepta un array y una función callback que determina el orden de ordenación. Analicémosla "bajo el capó".
¿Cómo funciona usort?
\n\nCuando llama a usort($array, $callback), PHP hace lo siguiente:
- \n
- Divide el array en pares de elementos. \n
- Para cada par, llama a su función callback. \n
- El callback debe devolver: un número negativo (si el primer elemento es "menor"), cero (si son iguales), un número positivo (si el primero es "mayor"). \n
- Basándose en estas respuestas, PHP reordena los elementos utilizando el algoritmo de ordenación rápida (Quicksort) o un híbrido del mismo. \n
Así es como se ve en código:
\n\n<?php\n$users = [\n ['name' => 'Анна', 'age' => 25],\n ['name' => 'Иван', 'age' => 30],\n ['name' => 'Мария', 'age' => 22]\n];\n\nusort($users, function($a, $b) {\n return $a['age'] - $b['age'];\n});\n\nprint_r($users);\n// Resultado: Мария (22), Анна (25), Иван (30)\n?>\n\nObserve: restamos la edad de $b de $a. Si $a['age'] es menor, el resultado es negativo, el elemento $a va primero. Sencillo como dos más dos.
La trampa: cadenas y sensibilidad a mayúsculas/minúsculas
\n\nSi ordena por un campo de cadena (por ejemplo, nombre), la resta no funcionará. Debe usar strcmp() o strcasecmp() para una ordenación que no distinga mayúsculas de minúsculas:
<?php\nusort($users, function($a, $b) {\n return strcmp($a['name'], $b['name']);\n});\n// Ordenación por nombre (Анна, Иван, Мария)\n?>\n\nPero tenga cuidado: strcmp() distingue entre mayúsculas y minúsculas. "apple" y "Apple" se considerarán diferentes. Si esto es crítico, use strcasecmp().
Solución n.º 2: array_multisort — potente pero astuto
\n\nLa segunda forma popular es array_multisort(). Esta función puede ordenar varios arrays a la vez o un array multidimensional por una columna. "Bajo el capó" funciona de manera diferente: extrae la columna, la ordena y luego reordena los demás arrays en el mismo orden.
Así es como se ve:
\n\n<?php\n$users = [\n ['name' =&g