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