Modificación dinámica de un array usando foreach y while
Se me ocurrió escribir esto cuando me encontraba escribiendo el código que aquí muestro y recordé que hacia mucho tiempo que no usaba foreach y while sobre un mismo array.
1 2 3 4 | foreach ($array as $key => $value) { // hacer algo con $value } |
Sabemos que foreach es la manera más fácil de iterar sobre un array y que es una construcción específica para ellos. En cambio while es una estructura de control general y que usada junto a la función list() también permite iterar sobre un array.
Yo empecé usando esta última forma, pero cuando descubrí foreach quedé encantado! Nunca más volvería a usar while-list. Además de lo engorrosa de la construcción no debes olvidar usar reset() antes, si quieres comenzar operando sobre el primer elemento del array.
O sea algo así:
Bueno, tiempo después, ahora no recuerdo que estaba haciendo exactamente, pero me volví a encontrar pensando “vaya, while-list, sí que que son buenos para los arrays, y con el reset, nada mejor”.
Y la razón de todo este tira y encoje se debe a una sencilla propiedad del foreach, y que estoy seguro es bastante desconocida:
“foreach opera sobre una copia del array, NO sobre el array original”
Antes de seguir dejemos en claro algo:
1.- foreach puede trabajar sobre el array original si este pasa sus valores por referencia.
1 2 | # una variable se pasa por referencia anteponiéndole un ampersand (&) foreach ($array as $key => &$value) |
Si no sabes nada de esto de pasar variables por referencia es mejor estudiarlo en la misma fuente: http://php.net/manual/es/language.references.php
2.- No es necesario usar reset() con foreach. Siempre empezará operando desde el primer elemento y seguirá en orden hasta el último. Pero no olvides que en general estará moviendose sobre una copia del array por lo que, por ejemplo, si estabas recorriendo el array original mediante una de las otras muchas funciones para arrays como array_keys() o each() su puntero interno seguirá apuntando al mismo elemento.
La razón de todo este bla-bla es el siguiente código. Lo escribí para dar solución al siguiente problema (seguro que te dará alguna buena idea para tus tareas).
Problema: Tengo una lista de automóviles cada uno con una o más de tres propiedades:
y estas propiedades no están necesariamente ordenadas:
Ej:
1 2 3 4 | Nissan V16: blanco, automático Chevrotet Corsa: bencina Toyota Corolla: diesel, mecánico, rojo ... |
Pregunta: Como reescribo esta lista encasillando correctamente sus propiedades (para ingresarlo a una base de datos relacional),
Ed:
1 2 3 4 5 6 7 | ------------------------------------------------------------ Auto Color Combustible Transmisión ------------------------------------------------------------ Nissan V16: blanco automático -- Chevrotet Corsa: -- bencina -- Toyota Corolla: rojo diesel mecánico ------------------------------------------------------------ |
Solución:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # $propertyCar contiene una o más propiedades del auto # ---------------------------------------------------- $arrayTransmission = array('manual','automatic','tiptronic','cvt'); $arrayFuel = array('petrol','diesel','hybrid','lpg','electric'); $arrayColour = array('silver','blue','black','red','grey','green'); $store['transmission'] = ''; foreach ($arrayTransmission as $val1) { reset($propertyCar); while (list ($var2,$val2) = each ($propertyCar)) { if (stristr($val2[1], $val1)) { $store['transmission'] = trim($val2[1]); unset($propertyCar[$var2]); break 2; } } } # lo mismo para # ------------- $store['fuel'] = ''; $store['colour'] = ''; |
Y finalmente, que fue de la “Modificación dinámica de un array…” Si te das cuenta:
1 2 3 4 5 6 7 8 | # aqui eliminamos un elemento del array original $propertyCar # ----------------------------------------------------------- unset($propertyCar[$var2]); # y salimos del doble bucle con 2 # primero del while y luego del foreach # ------------------------------------- break 2; |
Es decir, modificamos el array al mismo tiempo que operamos sobre él. En este caso lo vamos acortando para apurar los siguientes procesos que encontrarán los valores de $store['fuel'] y $store['colour'].
Con una lista enorme de automóviles como con la que me tocó trabajar este tipo de atenciones con el servidor se ven recompensadas con un ahorro de tiempo que ahora uso para escribir esto y con más paga que ahora usaré para una o más cervezas.
No hay comentarios
RSS feed para comentarios en este post
TrackBack URL

RSS Feed