Ok, esta es más una pregunta de informática, que una pregunta basada en un idioma en particular, pero ¿hay alguna diferencia entre una operación de mapa y una operación foreach? ¿O son simplemente nombres diferentes para la misma cosa?
foreach
language-agnostic
computer-science
map-function
Robert Gould
fuente
fuente
Iterator[String]
descala.io.Source.fromFile("/home/me/file").getLines()
y aplicarlo.foreach(s => ptintln(s))
a ella, se imprime bien, pero va directo vacía después. Al mismo tiempo, si lo solicito.map(ptintln(_))
, simplemente se vacía y no se imprime nada.Respuestas:
Diferente.
foreach itera sobre una lista y aplica alguna operación con efectos secundarios a cada miembro de la lista (como guardar cada uno en la base de datos, por ejemplo)
map itera sobre una lista, transforma a cada miembro de esa lista y devuelve otra lista del mismo tamaño con los miembros transformados (como convertir una lista de cadenas en mayúsculas)
fuente
map
no no da lugar a la ejecución de su lógica subyacente, hasta cuando la lista de espera es convocado transformado. Por el contrario,foreach
la operación se calcula de inmediato.La diferencia importante entre ellos es que
map
acumula todos los resultados en una colección, mientras queforeach
no devuelve nada.map
generalmente se usa cuando desea transformar una colección de elementos con una función, mientras queforeach
simplemente ejecuta una acción para cada elemento.fuente
En resumen,
foreach
es para aplicar una operación en cada elemento de una colección de elementos, mientras quemap
es para transformar una colección en otra.Hay dos diferencias significativas entre
foreach
ymap
.foreach
no tiene restricciones conceptuales sobre la operación que aplica, aparte de aceptar un elemento como argumento. Es decir, la operación puede no hacer nada, puede tener un efecto secundario, puede devolver un valor o puede no devolver un valor. Lo único queforeach
importa es iterar sobre una colección de elementos y aplicar la operación en cada elemento.map
, por otro lado, tiene una restricción en la operación: espera que la operación devuelva un elemento, y probablemente también acepte un elemento como argumento. Lamap
operación itera sobre una colección de elementos, aplicando la operación en cada elemento y finalmente almacenando el resultado de cada invocación de la operación en otra colección. En otras palabras,map
transforma una colección en otra.foreach
trabaja con una sola colección de elementos. Esta es la colección de entrada.map
funciona con dos colecciones de elementos: la colección de entrada y la colección de salida.No es un error relacionar los dos algoritmos: de hecho, puede ver los dos jerárquicamente, donde
map
hay una especializaciónforeach
. Es decir, puede usarforeach
y hacer que la operación transforme su argumento y lo inserte en otra colección. Entonces, elforeach
algoritmo es una abstracción, una generalización, delmap
algoritmo. De hecho, debido a queforeach
no tiene restricciones en su funcionamiento, podemos decir con seguridad queforeach
es el mecanismo de bucle más simple que existe y que puede hacer cualquier cosa que un bucle pueda hacer.map
, así como otros algoritmos más especializados, está ahí para la expresividad: si desea mapear (o transformar) una colección en otra, su intención es más clara si la usamap
que si la usaforeach
.Podemos extender más esta discusión y considerar el
copy
algoritmo: un ciclo que clona una colección. Este algoritmo también es una especialización delforeach
algoritmo. Podría definir una operación que, dado un elemento, inserte ese mismo elemento en otra colección. Si utilizaforeach
con esa operación, en realidad realizó elcopy
algoritmo, aunque con claridad, expresividad o explicidad reducidas. Vamos a ir aún más lejos: podemos decir quemap
es una especialización decopy
, en sí misma una especialización deforeach
.map
puede cambiar cualquiera de los elementos sobre los que itera. Simap
no cambia ninguno de los elementos, simplemente copia los elementos y usa la copia expresaría la intención más claramente.El
foreach
algoritmo en sí puede o no tener un valor de retorno, dependiendo del idioma. En C ++, por ejemplo,foreach
devuelve la operación que recibió originalmente. La idea es que la operación podría tener un estado, y es posible que desee volver a inspeccionar cómo evolucionó sobre los elementos.map
, también, puede o no devolver un valor. En C ++transform
(el equivalentemap
aquí) sucede que devuelve un iterador al final del contenedor de salida (colección). En Ruby, el valor de retorno demap
es la secuencia de salida (colección). Entonces, el valor de retorno de los algoritmos es realmente un detalle de implementación; su efecto puede o no ser lo que devuelven.fuente
.forEach()
se puede usar para implementar.map()
, consulte aquí: stackoverflow.com/a/39159854/1524693Array.protototype.map
método yArray.protototype.forEach
son bastante similares.Ejecute el siguiente código: http://labs.codecademy.com/bw1/6#:workspace
Dan el mismo resultado exacto.
Pero el giro se produce cuando ejecuta el siguiente código:
Aquí simplemente he asignado el resultado del valor de retorno del mapa y para cada método.
¡Ahora el resultado es algo complicado!
Conclusión
Array.prototype.map
devuelve una matriz peroArray.prototype.forEach
no lo hace. Por lo tanto, puede manipular la matriz devuelta dentro de la función de devolución de llamada pasada al método de mapa y luego devolverla.Array.prototype.forEach
solo recorre el conjunto dado para que pueda hacer sus cosas mientras recorre el conjunto.fuente
La diferencia más "visible" es que el mapa acumula el resultado en una nueva colección, mientras que foreach se realiza solo para la ejecución misma.
pero hay un par de supuestos adicionales: dado que el "propósito" del mapa es la nueva lista de valores, en realidad no importa el orden de ejecución. de hecho, algunos entornos de ejecución generan código paralelo, o incluso introducen algunas memorias para evitar pedir valores repetidos, o pereza, para evitar llamar a algunos.
foreach, por otro lado, se llama específicamente por los efectos secundarios; por lo tanto, el orden es importante y generalmente no puede ser paralelizado.
fuente
Respuesta corta:
map
yforEach
son diferentes. Además, hablando informalmente,map
es un estricto superconjunto deforEach
.Respuesta larga: Primero, elaboremos descripciones de una línea de
forEach
ymap
:forEach
itera sobre todos los elementos, llamando a la función proporcionada en cada uno.map
itera sobre todos los elementos, llama a la función proporcionada en cada uno y produce una matriz transformada al recordar el resultado de cada llamada a la función.En muchos idiomas, a
forEach
menudo se le llama justoeach
. La siguiente discusión usa JavaScript solo como referencia. Realmente podría ser cualquier otro idioma.Ahora, usemos cada una de estas funciones.
Utilizando
forEach
:Tarea 1: escriba una función
printSquares
que acepte una matriz de númerosarr
e imprima el cuadrado de cada elemento en ella.Solución 1:
Utilizando
map
:Tarea 2: Escriba una función
selfDot
, que acepta una matriz de númerosarr
, y devuelve una matriz en la que cada elemento es el cuadrado del elemento correspondiente enarr
.Aparte: Aquí, en términos de argot, estamos tratando de cuadrar la matriz de entrada. En términos formales, estamos tratando de calcular su producto punto consigo mismo.
Solución 2:
¿Cómo es
map
un superconjunto deforEach
?Puede usar
map
para resolver ambas tareas, Tarea 1 y Tarea 2 . Sin embargo, no puede usarforEach
para resolver la Tarea 2 .En la Solución 1 , si simplemente reemplaza
forEach
pormap
, la solución seguirá siendo válida. Sin embargo, en la Solución 2 , reemplazarmap
porforEach
romperá su solución que funcionaba anteriormente.Implementando
forEach
en términos demap
:Otra forma de darse cuenta
map
de la superioridad es implementarforEach
en términos demap
. Como somos buenos programadores, no nos permitiremos contaminar el espacio de nombres. Llamaremos a nuestroforEach
, soloeach
.Ahora, si no te gustan las
prototype
tonterías, aquí tienes:Entonces, umm .. ¿Por qué
forEach
existe?La respuesta es la eficiencia. Si no está interesado en transformar una matriz en otra matriz, ¿por qué debería calcular la matriz transformada? ¿Solo para tirarlo? ¡Por supuesto no! Si no quieres una transformación, no debes hacer una transformación.
Entonces, aunque el mapa se puede usar para resolver la Tarea 1 , probablemente no debería. Para cada uno es el candidato adecuado para eso.
Respuesta original:
Si bien estoy en gran medida de acuerdo con la respuesta de @madlep, me gustaría señalar que
map()
es un súper conjunto estricto deforEach()
.Sí,
map()
generalmente se usa para crear una nueva matriz. Sin embargo, también se puede usar para cambiar la matriz actual.Aquí hay un ejemplo:
En el ejemplo anterior,
a
se configuró convenientemente de modo quea[i] === i
parai < a.length
. Aun así, demuestra el poder demap()
.Aquí está la descripción oficial de
map()
. Tenga en cuenta quemap()
incluso puede cambiar la matriz en la que se llama. Granizomap()
.Espero que esto haya ayudado.
Editado el 10 de noviembre de 2015: elaboración adicional.
fuente
map
función nativa pero noforEach
; ¿No podrías simplemente no usar enmap
lugar deforEach
? Por otro lado, si un idioma tuvieraforEach
pero nomap
, tendrías que implementar el tuyomap
. No podrías simplemente usar enforEach
lugar demap
. Dime que piensas.Aquí hay un ejemplo en Scala usando listas: el mapa devuelve la lista, foreach no devuelve nada.
Entonces map devuelve la lista resultante de aplicar la función f a cada elemento de la lista:
Foreach solo aplica f a cada elemento:
fuente
Si está hablando de Javascript en particular, la diferencia es que
map
es una función de bucle mientras queforEach
es un iterador.Úselo
map
cuando desee aplicar una operación a cada miembro de la lista y recuperar los resultados como una nueva lista, sin afectar la lista original.Úselo
forEach
cuando desee hacer algo en función de cada elemento de la lista. Es posible que esté agregando cosas a la página, por ejemplo. Esencialmente, es ideal para cuando quieres "efectos secundarios".Otras diferencias:
forEach
no devuelve nada (ya que es realmente una función de flujo de control), y la función transferida obtiene referencias al índice y a la lista completa, mientras que map devuelve la nueva lista y solo pasa en el elemento actual.fuente
ForEach intenta aplicar una función como escribir en db, etc. en cada elemento del RDD sin devolver nada.
Pero
map()
aplica alguna función sobre los elementos de rdd y devuelve el rdd. Entonces, cuando ejecuta el método a continuación, no fallará en la línea 3, pero al recopilar el rdd después de aplicar foreach, fallará y arrojará un error que dicefuente