Una de las tareas que los programadores con poca experiencia encuentran muy difícil es ordenar Arrays multidimensionales mediante uno de los valores en los Child Arrays (Arreglos secundarios). En el tutorial de hoy les mostraré 3 maneras de lograrlo – Tú decides cual se te hace más sencillo y te proporciona el mejor desempeño.
Asumamos un escenario donde tenemos un Array muy grande, como el que se observa debajo, y necesitamos ordenarlo a través de un valor contenido en el último child array (arreglo secundario) – En nuestro caso el valor del ‘weight’ Key
<?php
$array = [
[
['name'=>'John B'],
['age'=>30],
['sizes'=>
[
'weight'=>80,
'height'=>120
]
]
],
[
['name'=>'Marie B'],
['age'=>31],
['sizes'=>
[
'weight'=>60,
'height'=>110
]
]
],
[
['name'=>'Carl M'],
['age'=>12],
['sizes'=>
[
'weight'=>70,
'height'=>100
]
]
],
[
['name'=>'Mike N'],
['age'=>19],
['sizes'=>
[
'weight'=>70,
'height'=>150
]
]
],
[
['name'=>'Nancy N'],
['age'=>15],
['sizes'=>
[
'weight'=>60,
'height'=>150
]
]
],
[
['name'=>'Cory X'],
['age'=>15],
['sizes'=>
[
'weight'=>44,
'height'=>150
]
]
]
];
?>
usort
y una simple función callback (Recomendado)
Este método es muy sencillo – usort
recorre automáticamente cada combinación de dos elementos del Array, compara cualquier cosa que quieras en la función callback, y devuelve -1 o 1 respectivamente, se encarga de asignar un index apropiado al elemento dado en el Array resultante. En nuestro caso, si ‘weight’ en $a es más pequeño o igual que ‘weight’ en $b, el contenido de $a terminará teniendo un index más pequeño en el Array a ser ordenado. Este es el código:
<?php
//Method1: sorting the array using the usort function and a "callback that you define"
function method1($a,$b)
{
return ($a[2]["sizes"]["weight"] <= $b[2]["sizes"]["weight"]) ? -1 : 1;
}
usort($array, "method1");
print_r($array);
?>
El método de Ordenamiento Burbuja es algo que la gente acostumbraba a aprender en computación en los ’90. Se sabe que es un método lento para reordenar y requiere recorrer el array varias veces.
El método de ordenamiento burbuja chequea cada set (colección) de valores adyacentes y si consigue la condición requerida cambiara sus posiciones. Esta acción se hace una y otra vez hasta que ya no es necesario reordenar en un Array completo. En este ejemplo el arreglo es recorrido hasta que todos los ´weight’ conseguidos en $j
son mas pequeños que los ‘weight’ conseguidos en $j+1
. Observa:
<?php
//Method 2: The bubble method
$j=0;
$flag = true;
$temp=0;
while ( $flag )
{
$flag = false;
for( $j=0; $j < count($array)-1; $j++)
{
if ( $array[$j][2]["sizes"]["weight"] > $array[$j+1][2]["sizes"]["weight"] )
{
$temp = $array[$j];
//swap the two between each other
$array[$j] = $array[$j+1];
$array[$j+1]=$temp;
$flag = true; //show that a swap occurred
}
}
}
print_r($array);
?>
Algunos programadores prefieren simplemente escribir sus propios códigos para estas tareas, por eso pensé en darte un ejemplo de un código custom (a la medida) para lograr el mismo resultado.
La manera que diseñe es bastante directa:
Primero crea un array temporal vacío, luego recorre el array que necesita ser ordenado y reemplaza las keys existentes con los valores por lo que estas ordenando. Por favor nota que también necesitas asegurarte que las nuevas keys sean únicas para no perder ningún elemento. En mi caso – Decidí usar las viejas keys y añadirlas a las nuevas para que las keys resultantes sean algo como: "new_key" . "some_string" . "old_unique_key". Luego ordene el array temporal por key usando la función ksort()
y use valores del array para reordenar el arreglo numéricamente. Este es el código:
Por favor nota que el código que se muestra debajo puede que no funcione correctamente en algunos casos. Por ejemplo, si uno de los ‘weight’ sea más o igual que 100, entonces la función ksort fallará en dar el resultado correcto. Puedes usar ksort($temp, SORT_NATURAL)
en dado caso.
<?php
//Method3: DIY
$temp = [];
foreach ($array as $key => $value)
$temp[$value[2]["sizes"]["weight"] . "oldkey" . $key] = $value; //concatenate something unique to make sure two equal weights don't overwrite each other
ksort($temp); // or ksort($temp, SORT_NATURAL); see paragraph above to understand why
$array = array_values($temp);
unset($temp);
print_r($array);
?>