php - obtener - tags wordpress codex
Colecciones elocuentes: cada uno frente a foreach (5)
Al contrario de lo que dicen las otras dos respuestas, Collection::each()
no cambia los valores de los elementos en la Colección, técnicamente hablando. Utiliza array_map()
, pero no almacena el resultado de esa llamada.
Si desea modificar cada elemento de una colección (por ejemplo, para convertirlos en objetos como Damon en un comentario a la respuesta aceptada por los demás), entonces debe usar Collection::map()
. Esto creará una nueva colección basada en el resultado de la llamada subyacente a array_map()
.
Puede que no sea una pregunta específica para colecciones Eloquent, pero me golpeó mientras trabajaba con ellos. Supongamos que tenemos un objeto $collection
que es una instancia de Illuminate/Support/Collection
.
Ahora, si queremos iterar sobre él, ¿cuáles son los pros y los contras de usar each()
con un cierre frente a un foreach
regular? ¿Hay alguna?
foreach ($collection as $item) {
// Some code
}
--- VS ---
$collection->each(function ($item) {
// Some code
});
Es más beneficioso usar este último: cada uno ().
Puede encadenar condiciones y escribir un código más expresivo y claro, por ejemplo:
$ example-> each () -> map () -> filter ();
Esto lo lleva más cerca de la Programación Declarativa, donde le dice a la computadora qué debe lograr en lugar de cómo lograrlo.
Algunos artículos útiles:
Hay mucha confusión de información errónea en las respuestas existentes.
La respuesta corta
La respuesta corta es: no hay diferencia importante entre usar .each()
vs. foreach
para iterar sobre una colección de Laravel. Ambas técnicas logran el mismo resultado.
¿Qué hay de modificar los artículos?
Si usted está modificando o no los artículos es irrelevante si usa .each()
vs. foreach
. Ambos lo hacen (¡y no lo hacen!) Y le permiten modificar los elementos de la colección según el tipo de elementos de los que estamos hablando.
- Modificar elementos si la Colección contiene objetos : si la Colección es un conjunto de objetos PHP (como una Colección Eloquent), cada
.each()
oforeach
permiten modificar propiedades de los objetos (como$item->name = ''foo''
). Eso se debe simplemente a cómo los objetos PHP siempre actúan como referencias. Si está tratando de reemplazar el objeto completo con un objeto diferente (un escenario menos común), use en su lugar.map()
. - Modificar elementos si la Colección contiene no objetos : Esto es menos común, pero si su Colección contiene objetos no, como cadenas,
.each()
no le da una manera de modificar los valores de los elementos de la colección. (El valor de retorno del cierre se ignora). Use en su lugar.map()
.
Entonces ... ¿cuál debería usar?
En caso de que te estés preguntando sobre el rendimiento, hice varias pruebas con grandes colecciones de elementos Eloquent y una colección de cadenas. En ambos casos, el uso de foreach
fue más rápido que .each()
. Pero estamos hablando de microsegundos. En la mayoría de los escenarios de la vida real, la diferencia de velocidad no sería significativa en comparación con el tiempo que lleva acceder a la base de datos, etc.
Principalmente se reduce a tus preferencias personales. Usar .each()
es bueno porque puede encadenar varias operaciones juntas (por ejemplo .where(...).each(...)
). Tiendo a usar ambos en mi propio código solo dependiendo de lo que parece más limpio para cada situación.
La construcción foreach () no le permite cambiar el valor del elemento de la matriz que se está iterando, a menos que pase la matriz por referencia.
foreach ($array as &$value) $value *= $value;
El método elocuente cada () envuelve la función PHP array_map (), que permite esto.
Al igual que la respuesta anterior, debe usar foreach () si tiene alguna otra motivación. Esto se debe a que el rendimiento de foreach () es mucho mejor que array_map ().
http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/
Una declaración foreach
debe usarse como una especie de forma de recorrer una colección y realizar algún tipo de lógica sobre ella. Si lo que hay dentro afecta otras cosas en el programa, entonces use este ciclo.
El método .each
usa array_map
para recorrer cada uno de los objetos en la colección y realizar un cierre en cada uno. Luego devuelve la matriz resultante. Esa es la clave! .each
debe usarse si desea cambiar la colección de alguna manera. Tal vez sea una serie de autos y quieras que el modelo sea una mayúscula o minúscula. Simplemente pasará un cierre al método .each
que toma el objeto y llama a strtoupper()
en el modelo de cada objeto de Carro. A continuación, devuelve la colección con los cambios que se han realizado.
La moral de la historia es la siguiente: utilice el método .each
para cambiar cada elemento de la matriz de alguna manera; use el ciclo foreach
para usar cada objeto para afectar alguna otra parte del programa (usando alguna instrucción lógica).
ACTUALIZACIÓN (7 de junio de 2015)
Como se dijo Elocuentemente (¿ves lo que hice allí?) A continuación, la respuesta anterior está un poco apagada. El método .each
usando array_map
nunca usó realmente el resultado de la llamada array_map
. Por lo tanto, la nueva matriz creada por array_map
no se guardará en la Collection
. Para cambiarlo, es mejor utilizar el método .map
, que también existe en un objeto Collection
.
Usar una instrucción foreach
para iterar sobre cada uno de ellos tiene más sentido porque no podrá acceder a variables fuera del Cierre a menos que se asegure de usar una declaración de use
, lo cual me parece incómodo.
La implementación cuando la respuesta anterior se escribió originalmente se puede encontrar aquí .
.each
en Laravel 5.1
El nuevo. .each
que están hablando a continuación ya no usa array_map
. Simplemente itera a través de cada elemento en la colección y llama a la $callback
pasado, pasándole el elemento y su clave en la matriz. Funcionalmente, parece funcionar de la misma manera. Creo que usar un ciclo foreach
tendría más sentido al leer el código. Sin embargo, veo los beneficios de usar .each
porque le permite encadenar métodos juntos si eso le hace cosquillas a su imaginación. También le permite devolver un mensaje falso a partir de la devolución de llamada para abandonar el ciclo anticipadamente si su lógica comercial lo exige.
Para obtener más información sobre la nueva implementación, consulte el código fuente .