IronWoods.es

Desarrollo web

Blog / PHP / Funciones nativas y arrays asociativos

Los arrays son una de las estructuras más usadas y entre estos, los arrays simples, los que tienen un índice numérico. Por eficiencia, la mayoría de las funciones nativas funcionan de la forma "adecuada" sólo con estos, lo que nos deja a nosotros el trabajo de implementar ciertos comportamientos en arrays asociativos.

El día de la marmota

Una tarde de invierno, casi por aburrimiento, me puse a hacer el script más tonto del mundo. Los test unitarios y funcionales pasaban OK, salvo unas pocas veces que quedaban en suspensión, como la marmota que se niega a dejar la madriguera: puede qué porque hace frío o porque está en el cielo de las marmotas, ¿quién sabe?

Como los test no indicaban ningún error, tuve que revisar el código, puse trazas y empecé a revisar todo el flujo sin encontrar nada. Mirando más a fondo vi un par de cosas sospechosas.

Probando una alternativa, los test comenzaron a fallar, no siempre, pero fallaban en ciertas condiciones, cuando se llamaba a una función de manipulación de arrays que no funcionaba como yo creía: array_pop().

Asociativos o no asociativos

Abrí una caja de arena de PHP (sandbox) para un par de pruebas rápidas y ¡Eureka! La función array_pop( ) extrae el último valor del array y lo devuelve, acortando el array en un elemento, esto también es así con un array de tipo asociativo, es decir que obtenemos su valor, no el elemento en sí mismo: ¡hemos perdido la clave!

Veamos un ejemplo:

$diet = [

'desayuno' => 'plátano',

'comida' => 'manzana',

'cena' => 'sandía',

];


$slice = array_pop($diet);


Hemos "extraído" el último elemento del array, ahora sólo contiene desayuno y comida:

$diet = [

'desayuno' => 'plátano',

'comida' => 'manzana',

];


Además, podríamos esperar tener también el siguiente array:

$slice = [

'cena' => 'sandía',

];


Pero no. Tenemos esto:

$slice = 'sandía';

Obteniendo tan sólo el valor de la pareja: "clave" => "valor", podemos tener un problema con ciertos scripts donde la clave contiene un dato útil que no queremos perder, y este fue mi caso, no leí la documentación oficial de la función.

Otra función relacionada con array_pop() y que funciona de igual modo: array_shift(), sólo que en este caso se extrae el primer elemento del array (y se devuelve su valor).

Implementando soluciones...

Podemos implementar funciones, para trabajar con arrays asociativos, como las siguientes:

function array_pop_assoc(array &$arr)

{

$slice = array_slice($arr, (count($arr) - 1));

array_pop($arr);


return $slice;

}


function array_shift_assoc(array &$arr)

{

$slice = array_slice($arr, 0, 1);

array_shift($arr);


return $slice;

}


Una mejora de las funciones anteriores, que extrae y elimina el elemento en un sólo paso, propuesta en StackOverflow, podría ser:

function array_pop_assoc(array &$arr)

{

return array_splice($arr, (count($arr) - 1));

}


function array_shift_assoc(array &$arr)

{

return array_splice($arr, 0, 1);

}


Estas funciones, trabajan con arrays asociativos y no asociativos, pero en base al rendimiento, solo deben usarse en los casos necesarios.


29-12-2017