Ok, isso é mais uma questão de ciência da computação do que uma questão baseada em um idioma específico, mas existe uma diferença entre uma operação de mapa e uma operação foreach? Ou eles são simplesmente nomes diferentes para a mesma coisa?
foreach
language-agnostic
computer-science
map-function
Robert Gould
fonte
fonte
Iterator[String]
dosscala.io.Source.fromFile("/home/me/file").getLines()
e aplicar.foreach(s => ptintln(s))
a ele, ele é impresso ok, mas fica certo vazio depois. Ao mesmo tempo, se eu aplicar.map(ptintln(_))
, ele fica vazio e nada é impresso.Respostas:
Diferente.
O foreach itera sobre uma lista e aplica alguma operação com efeitos colaterais a cada membro da lista (como salvar cada um no banco de dados, por exemplo)
O mapa itera sobre uma lista, transforma cada membro dessa lista e retorna outra lista do mesmo tamanho com os membros transformados (como converter uma lista de cadeias de caracteres em maiúsculas)
fonte
map
que não resultam na execução de sua lógica subjacente até quando a lista transformado esperado é convocado. Por outro lado,foreach
a operação é calculada imediatamente.A diferença importante entre eles é que
map
acumula todos os resultados em uma coleção, enquantoforeach
não retorna nada.map
geralmente é usado quando você deseja transformar uma coleção de elementos com uma função, enquantoforeach
simplesmente executa uma ação para cada elemento.fonte
Em resumo,
foreach
é para aplicar uma operação em cada elemento de uma coleção de elementos, ao passo quemap
é para transformar uma coleção em outra.Existem duas diferenças significativas entre
foreach
emap
.foreach
não possui restrições conceituais sobre a operação que aplica, além de talvez aceitar um elemento como argumento. Ou seja, a operação pode não fazer nada, pode ter um efeito colateral, pode retornar um valor ou pode não retornar um valor. O queforeach
importa é iterar sobre uma coleção de elementos e aplicar a operação em cada elemento.map
, por outro lado, tem uma restrição à operação: espera que a operação retorne um elemento e provavelmente também aceite um elemento como argumento. Amap
operação itera sobre uma coleção de elementos, aplicando a operação em cada elemento e, finalmente, armazenando o resultado de cada chamada da operação em outra coleção. Em outras palavras, omap
transforma uma coleção em outra.foreach
trabalha com uma única coleção de elementos. Esta é a coleção de entrada.map
trabalha com duas coleções de elementos: a coleção de entrada e a coleção de saída.Não é um erro relacionar os dois algoritmos: na verdade, você pode visualizar os dois hierarquicamente, de onde
map
é uma especializaçãoforeach
. Ou seja, você pode usarforeach
e fazer com que a operação transforme seu argumento e o insira em outra coleção. Portanto, oforeach
algoritmo é uma abstração, uma generalização, domap
algoritmo. De fato, comoforeach
não há restrição em sua operação, podemos dizer com segurança que esseforeach
é o mecanismo de loop mais simples existente no mercado e pode fazer qualquer coisa que um loop possa fazer.map
, além de outros algoritmos mais especializados, existe expressividade: se você deseja mapear (ou transformar) uma coleção em outra, sua intenção é mais clara se você usar domap
que se usarforeach
.Podemos estender mais essa discussão e considerar o
copy
algoritmo: um loop que clona uma coleção. Este algoritmo também é uma especialização doforeach
algoritmo. Você pode definir uma operação que, dado um elemento, insira esse mesmo elemento em outra coleção. Se você usarforeach
essa operação, você efetivamente executou ocopy
algoritmo, embora com menor clareza, expressividade ou explicitação. Vamos levar ainda mais longe: podemos dizer quemap
é uma especialização decopy
, ela própria uma especialização deforeach
.map
pode alterar qualquer um dos elementos que itera. Semap
não altera nenhum dos elementos, apenas copia os elementos e usa copy expressaria a intenção mais claramente.O
foreach
próprio algoritmo pode ou não ter um valor de retorno, dependendo do idioma. Em C ++, por exemplo,foreach
retorna a operação que recebeu originalmente. A idéia é que a operação possa ter um estado, e você pode querer que ela volte a inspecionar como evoluiu sobre os elementos.map
também pode ou não retornar um valor. Em C ++transform
(o equivalentemap
aqui) retorna um iterador para o final do contêiner de saída (coleção). No Ruby, o valor de retornomap
é a sequência de saída (coleção). Portanto, o valor de retorno dos algoritmos é realmente um detalhe de implementação; seu efeito pode ou não ser o que eles retornam.fonte
.forEach()
pode ser usado para implementar.map()
, consulte aqui: stackoverflow.com/a/39159854/1524693 #Array.protototype.map
método eArray.protototype.forEach
são ambos bastante semelhantes.Execute o seguinte código: http://labs.codecademy.com/bw1/6#:workspace
Eles dão o mesmo resultado.
Mas a reviravolta ocorre quando você executa o seguinte código: -
Aqui, eu simplesmente atribuí o resultado do valor de retorno dos métodos map e forEach.
Agora o resultado é algo complicado!
Conclusão
Array.prototype.map
retorna uma matriz, masArray.prototype.forEach
não. Portanto, você pode manipular a matriz retornada dentro da função de retorno de chamada passada para o método map e depois devolvê-la.Array.prototype.forEach
apenas percorre a matriz fornecida para que você possa fazer suas coisas enquanto caminha pela matriz.fonte
a diferença mais "visível" é que o mapa acumula o resultado em uma nova coleção, enquanto o foreach é feito apenas para a própria execução.
mas há algumas suposições extras: como o "objetivo" do mapa é a nova lista de valores, isso realmente não importa a ordem de execução. de fato, alguns ambientes de execução geram código paralelo ou até introduzem algumas memoizing para evitar exigir valores repetidos, ou preguiça, para evitar chamar alguns.
o foreach, por outro lado, é chamado especificamente para os efeitos colaterais; portanto, a ordem é importante e geralmente não pode ser paralelizada.
fonte
Resposta curta:
map
eforEach
são diferentes. Além disso, informalmente,map
é um superconjunto estrito deforEach
.Resposta longa: Primeiro, vamos apresentar descrições de uma linha
forEach
emap
:forEach
itera sobre todos os elementos, chamando a função fornecida em cada um.map
itera sobre todos os elementos, chamando a função fornecida em cada um e produz uma matriz transformada lembrando o resultado de cada chamada de função.Em muitos idiomas,
forEach
costuma ser chamado apenaseach
. A discussão a seguir usa JavaScript apenas para referência. Poderia realmente ser qualquer outro idioma.Agora, vamos usar cada uma dessas funções.
Usando
forEach
:Tarefa 1: Escreva uma função
printSquares
que aceite uma matriz de númerosarr
e imprima o quadrado de cada elemento nela.Solução 1:
Usando
map
:Tarefa 2: Escreva uma função
selfDot
que aceite uma matriz de númerosarr
e retorne uma matriz em que cada elemento é o quadrado do elemento correspondente emarr
.Além: Aqui, em termos de gíria, estamos tentando quadrar o array de entrada. Em termos gerais, estamos tentando calcular o produto escalar consigo mesmo.
Solução 2:
Como é
map
um superconjunto deforEach
?Você pode usar
map
para resolver as duas tarefas, Tarefa 1 e Tarefa 2 . No entanto, você não pode usarforEach
para resolver a tarefa 2 .Na solução 1 , se você simplesmente substituir
forEach
pormap
, a solução ainda será válida. Na solução 2 , no entanto, a substituiçãomap
porforEach
interromperá a solução que estava funcionando anteriormente.Implementação
forEach
em termos demap
:Outra maneira de perceber
map
a superioridade é implementarforEach
em termos demap
. Como somos bons programadores, não vamos entrar em poluição por namespace. Vamos ligar para o nossoforEach
, apenaseach
.Agora, se você não gosta do
prototype
absurdo, aqui está:Então, umm .. Por que faz
forEach
existe?A resposta é eficiência. Se você não está interessado em transformar uma matriz em outra matriz, por que calcular a matriz transformada? Apenas para despejar? Claro que não! Se você não quer uma transformação, não deve fazer uma transformação.
Portanto, embora o mapa possa ser usado para resolver a Tarefa 1 , provavelmente não deveria. Pois cada um é o candidato certo para isso.
Resposta original:
Embora eu concorde amplamente com a resposta de @madlep, gostaria de salientar que esse
map()
é um superconjunto estrito deforEach()
.Sim,
map()
geralmente é usado para criar uma nova matriz. No entanto, também pode ser usado para alterar a matriz atual.Aqui está um exemplo:
No exemplo acima,
a
foi convenientemente definidoa[i] === i
para quei < a.length
. Mesmo assim, demonstra o poder demap()
.Aqui está a descrição oficial de
map()
. Observe quemap()
pode até alterar a matriz na qual é chamada! Salvemap()
.Espero que isso tenha ajudado.
Editado em 10/11/2015: Elaboração adicionada.
fonte
map
função nativa , mas nãoforEach
; você simplesmente não poderia usar emmap
vez deforEach
? Por outro lado, se um idioma tivesseforEach
mas nãomap
, você teria que implementar o seu própriomap
. Você não poderia simplesmente usar emforEach
vez demap
. Me diga o que você acha.Aqui está um exemplo no Scala usando listas: mapa retorna lista, foreach não retorna nada.
Portanto, map retorna a lista resultante da aplicação da função f em cada elemento da lista:
O Foreach apenas aplica f a cada elemento:
fonte
Se você está falando sobre Javascript em particular, a diferença é que
map
é uma função de loop enquantoforEach
é um iterador.Use
map
quando quiser aplicar uma operação a cada membro da lista e obter os resultados novamente como uma nova lista, sem afetar a lista original.Use
forEach
quando quiser fazer algo com base em cada elemento da lista. Você pode adicionar coisas à página, por exemplo. Essencialmente, é ótimo para quando você deseja "efeitos colaterais".Outras diferenças:
forEach
não retorna nada (já que é realmente uma função de fluxo de controle), e a função transmitida obtém referências ao índice e a lista inteira, enquanto o mapa retorna a nova lista e passa apenas no elemento atual.fonte
O ForEach tenta aplicar uma função como escrever em db etc em cada elemento do RDD sem retornar nada.
Mas o
map()
aplica alguma função sobre os elementos de rdd e retorna o rdd. Portanto, quando você executa o método abaixo, ele não falha na linha3, mas ao coletar o rdd após aplicar o foreach, ele falha e gera um erro que dizfonte