Hay una diferencia entre el foreach y el mapa?
-
21-08-2019 - |
Pregunta
Aceptar esto es más de un equipo de ciencias de la cuestión, que una pregunta basada en un idioma en particular, pero hay una diferencia entre un mapa de la operación y un foreach de la operación?O son, simplemente, diferentes nombres para la misma cosa?
Solución
diferente.
itera foreach más de una lista y aplica alguna operación con efectos secundarios a cada miembro de la lista (tales como el ahorro de cada uno para la base de datos por ejemplo)
mapa itera sobre una lista, transforma cada miembro de esa lista, y devuelve otra lista del mismo tamaño con los miembros transformadas (como la conversión de una lista de cadenas a mayúsculas)
Otros consejos
La importante diferencia entre ellos es que map
acumula todos los resultados en una colección, mientras que foreach
no devuelve nada. <=> se utiliza generalmente cuando se desea transformar un conjunto de elementos con una función, mientras que <=> simplemente ejecuta una acción para cada elemento.
En definitiva, foreach
es para la aplicación de una operación sobre cada elemento de una colección de elementos, mientras que map
es para la transformación de una colección a otra.
Hay dos diferencias significativas entre foreach
y map
.
foreach
no tiene conceptual restricciones en la operación que se aplica, exceptuando, tal vez, aceptar un elemento como argumento.Es decir, la operación puede no hacer nada, puede tener un efecto secundario, puede devolver un valor o no puede devolver un valor.Todosforeach
que le interesa es para iterar sobre una colección de elementos, y aplicar el funcionamiento de cada elemento.map
, por otro lado, tiene una restricción en la operación:se espera que la operación de retorno de un elemento, y probablemente también aceptar un elemento como argumento.Elmap
la operación se itera a través de una colección de elementos, la aplicación de 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, lamap
transforma una colección a otra.foreach
funciona con una única colección de elementos.Esta es la recopilación de entrada.map
funciona con dos colecciones de elementos:la recopilación de entrada y la de salida de la colección.
No es un error de relacionar los dos algoritmos:de hecho, usted puede ver los dos jerárquicamente, donde map
es una especialización de foreach
.Es decir, usted podría utilizar foreach
y la operación de transformar su argumento y la inserta en otra colección.Así, la foreach
algoritmo es una abstracción, generalización, de la map
el algoritmo.De hecho, debido a que foreach
no tiene ninguna restricción en su operación, podemos decir con seguridad que foreach
es el más simple bucle mecanismo existe y nada puede hacer un bucle puede hacer. map
, así como otras más especializadas algoritmos, hay para expresividad:si usted desea asignar (o transformación) de una colección a otra, su intención es más clara si se utiliza map
que si usted lo usa foreach
.
Podemos extender este debate, y considerar la copy
algoritmo:un bucle que los clones de una colección.Este algoritmo también es una especialización de la foreach
el algoritmo.Se podría definir una operación que, dado un elemento de insertar ese mismo elemento en otra colección.Si usted utiliza foreach
con esa operación que en efecto realizó el copy
algoritmo, aunque con menor claridad, expresividad o lo explícito.Vamos a ir aún más allá:Podemos decir que map
es una especialización de copy
, una especialización de foreach
. map
puede cambio cualquiera de los elementos que recorre.Si map
no cambiar cualquiera de los elementos, a continuación, simplemente copiado los elementos, y el uso de copia expresa la intención más claramente.
El foreach
algoritmo de sí mismo puede o no puede 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 haber un estado, y desea que la operación de vuelta para inspeccionar cómo ha evolucionado a lo largo de los elementos. map
, también, puede o no puede devolver un valor.En C++ transform
(el equivalente de map
aquí) pasa a devolver un iterador al final de la salida de contenedor (colección).En Ruby, el valor de retorno map
es la secuencia de salida (colección).Así, el valor de retorno de los algoritmos es realmente un detalle de implementación;su efecto puede o puede no ser lo que ellos regresen.
método Array.protototype.map
& Array.protototype.forEach
son ambos bastante similar.
Ejecutar el siguiente código: http://labs.codecademy.com/bw1/6#:workspace
var arr = [1, 2, 3, 4, 5];
arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
console.log();
arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
Le dan el resultado exacto ídem.
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
Pero el giro se produce cuando se ejecuta el código siguiente: -
Aquí simplemente he asignado el resultado del valor de retorno del mapa y forEach métodos.
var arr = [1, 2, 3, 4, 5];
var ar1 = arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar1);
console.log();
var ar2 = arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar2);
console.log();
Ahora el resultado es algo difícil!
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
[ 1, 2, 3, 4, 5 ]
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
undefined
Conclusión
Array.prototype.map
devuelve una matriz pero Array.prototype.forEach
no. Así se puede manipular la matriz devuelta dentro de la función de devolución de llamada se pasa al método mapa y luego devolverlo.
<=> sólo se camina a través de la matriz dada para que pueda hacer sus cosas mientras camina la matriz.
La diferencia más 'visible' es que el mapa se acumula el resultado en una nueva colección, mientras que foreach se realiza sólo para la propia ejecución.
, pero hay un par de supuestos adicionales: ya que el 'propósito' del mapa es la nueva lista de valores, que en realidad no importa el orden de ejecución. de hecho, algunos entornos de ejecución generan código paralelo, o incluso introducen alguna memoizing para evitar llamar para valores repetidos, o pereza, para evitar llamar alguna en absoluto.
foreach, por otro lado, se llama específicamente para los efectos secundarios; por lo tanto, el orden es importante, y por lo general no puede ser paralelizado.
Respuesta corta: map
y forEach
son diferentes.También, informalmente hablando, map
es un estricto superconjunto de forEach
.
Respuesta larga: En primer lugar, vamos a venir para arriba con una línea de descripciones de forEach
y map
:
forEach
recorre todos los elementos, llamando a la función proporcionados en cada uno.map
recorre todos los elementos, llamando a la función proporcionados en cada uno, y se produce una transformación de la matriz por recordar el resultado de cada llamada a la función.
En muchos idiomas, forEach
a menudo es llamado simplemente each
.La siguiente discusión utiliza JavaScript sólo para referencia.Lo que realmente podría ser cualquier otro idioma.
Ahora, vamos a usar cada una de estas funciones.
El uso de forEach
:
Tarea 1: Escribir una función printSquares
, que acepta una matriz de números arr
, y se imprime el cuadrado de cada elemento en ella.
Solución 1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
El uso de map
:
Tarea 2: Escribir una función selfDot
, que acepta una matriz de números arr
, y devuelve un array donde cada elemento es el cuadrado del elemento correspondiente en arr
.
A un lado:Aquí, en términos de la jerga, estamos tratando de la plaza de la matriz de entrada.Formalmente, estamos tratando de calcular es producto escalar con sí mismo.
Solución 2:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
Cómo es map
un superconjunto de forEach
?
Puede utilizar map
para resolver ambas tareas, Tarea 1 y Tarea 2.Sin embargo, no se puede utilizar forEach
para resolver el Tarea 2.
En Solución 1, si usted simplemente reemplazar forEach
por map
, la solución sigue siendo válido.En Solución 2 sin embargo, la sustitución de map
por forEach
te rompen el anteriormente solución de trabajo.
La aplicación de forEach
en términos de map
:
Otra forma de darse cuenta de map
's superioridad es implementar forEach
en términos de map
.Como somos buenos programadores, vamos a no disfrutar en el espacio de nombres de la contaminación.Vamos a llamar a nuestro forEach
, sólo each
.
Array.prototype.each = function (func) {
this.map(func);
};
Ahora, si no te gusta el prototype
tonterías, aquí vamos:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
Así, umm..¿Por qué no forEach
incluso existen?
La respuesta es la eficiencia.Si usted no está interesado en transformar una matriz en otra matriz, ¿por qué debería calcular la transformada de la matriz?Sólo para la descarga?Por supuesto que no!Si usted no quiere una transformación, que no debe hacer una transformación.
Así, mientras que el mapa puede ser usado para resolver Tarea 1, probablemente no.Para cada uno es el candidato de la derecha para que.
Original respuesta:
Mientras estoy completamente de acuerdo con @madlep 's respuesta, me gustaría señalar que map()
es un estricto super-set de forEach()
.
Sí, map()
se utiliza generalmente para crear una nueva matriz.Sin embargo, es posible que también se utiliza para cambiar la matriz actual.
He aquí un ejemplo:
var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16]
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]
En el ejemplo anterior, a
fue convenientemente configurados de tal manera que a[i] === i
para i < a.length
.Aun así, se demuestra el poder de map()
.
Aquí está la descripción oficial de map()
.Tenga en cuenta que map()
incluso pueden cambiar la matriz en la que está llamado!El granizo map()
.
Espero que esta ayuda.
Editado 10-Nov-2015:Añadido elaboración.
Este es un ejemplo en el uso de listas Scala: Mapa de la lista regresa, foreach no devuelve nada.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
Así mapa vuelve a la lista resultante de la aplicación de la función f para cada elemento de la lista:
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)
Foreach simplemente aplica f a cada elemento:
scala> var sum = 0
sum: Int = 0
scala> list foreach (sum += _)
scala> sum
res2: Int = 6 // res1 is empty
Si usted está hablando de Javascript, en particular, la diferencia es que map
es una función de bucle mientras forEach
es un iterador.
Utilice <=> cuando se desea aplicar una operación para cada miembro de la lista y obtener los resultados como una nueva lista, sin afectar a la lista original.
Utilice <=> cuando se quiere lo algo sobre la base de cada elemento de la lista. Es posible que a añadir cosas a la página, por ejemplo. En esencia, es genial para cuando se desea "efectos secundarios".
Otras diferencias: <=> devuelve nada (ya que es realmente una función de control de flujo), y la función pasada en obtiene referencias al índice y toda la lista, mientras que un mapa devuelve la nueva lista y sólo permite el paso de la corriente elemento.
ParaCada trata de aplicar una función tal como escribir a db etc en cada elemento de la RDD sin devolver nada a cambio.
Pero el map()
aplica alguna función en los elementos de RDD y devuelve el RDD. Así que cuando se ejecuta el método siguiente no fallará en línea 3, pero durante la percepción de la RDD después de aplicar forEach se producirá un error y lanzar un error que dice
Archivo "
", línea 5, en AttributeError: objeto 'NoneType' no tiene atributo 'recoger'
nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())