Pergunta

Ok esta é mais uma questão de ciência da computação, do que uma pergunta com base em uma linguagem particular, mas há uma diferença entre uma operação de mapa e uma operação de foreach? Ou são simplesmente nomes diferentes para a mesma coisa?

Foi útil?

Solução

diferente.

itera foreach mais de uma lista e aplica-se alguma operação com efeitos colaterais para cada membro da lista (tais como poupança de cada um para o banco de dados, por exemplo)

mapa itera sobre uma lista, transforma cada membro da referida lista, e volta outra lista do mesmo tamanho com os membros transformadas (tais como a conversão de uma lista de strings em maiúsculas)

Outras dicas

A diferença importante entre eles é que map acumula todos os resultados em uma coleção, enquanto foreach retorna nada. map geralmente é usado quando você quer transformar uma coleção de elementos com uma função, enquanto foreach simplesmente executa uma ação para cada elemento.

Em suma, foreach é para aplicar uma operação em cada elemento de um conjunto de elementos, enquanto map é para transformar uma coleção para outra.

Existem duas diferenças significativas entre foreach e map.

  1. foreach não tem restrições conceituais sobre a operação se aplica, à excepção 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 não pode retornar um valor. Todos os cuidados foreach cerca é para iterar sobre uma coleção de elementos, e aplicar a operação em cada elemento.

    map, por outro lado, tem uma restrição sobre a operação: ele espera que a operação para retornar um elemento, e provavelmente também aceitar um elemento como argumento. A operação map itera sobre um conjunto de elementos, a aplicação da operação em cada elemento, e, finalmente, armazenando o resultado de cada invocação da operação para uma outra recolha. Em outras palavras, o map transforma uma coleção para outra.

  2. foreach trabalha com um único conjunto de elementos. Esta é a coleção de entrada.

    map trabalha com duas coleções de elementos:. A coleção de entrada ea coleta de saída

Não é um erro relacionar os dois algoritmos: na verdade, você pode ver os dois hierarquicamente, onde map é uma especialização de foreach. Ou seja, você poderia usar foreach e ter a operação de transformar seu argumento e inseri-lo em uma outra coleção. Assim, o algoritmo foreach é uma abstração, uma generalização, do algoritmo map. Na verdade, porque foreach não tem nenhuma restrição sobre o seu funcionamento, podemos dizer com segurança que foreach é o mais simples mecanismo de loop lá fora, e ele pode fazer qualquer coisa um loop pode fazer. map, bem como outros algoritmos mais especializado, está lá para expressividade: se você deseja mapear (ou transformar) uma coleção para outra, sua intenção é clara, se você usar map do que se você usar foreach

.

Podemos estender essa discussão adiante, e considerar o algoritmo copy: um laço que clona uma coleção. Este algoritmo também é uma especialização do algoritmo foreach. Pode-se definir uma operação que, tendo em conta um elemento, que irá inserir mesmo elemento para uma outra recolha. Se você usar foreach com essa operação que com efeito executou o algoritmo copy, embora com reduzida clareza, expressividade ou explicitação. Vamos levá-lo ainda mais longe: Podemos dizer que map é uma especialização de copy,-se uma especialização de foreach. map podem mudança qualquer um dos elementos que itera sobre. Se map não muda qualquer um dos elementos, em seguida, ele apenas Copiado os elementos, e usando cópia expressaria a intenção mais clara.

O algoritmo foreach em si pode ou não pode ter um valor de retorno, dependendo do idioma. Em C ++, por exemplo, foreach retorna a operação que originalmente recebido. A ideia é que a operação pode ter um estado, e você pode querer que volta de operações para verificar como ele evoluiu ao longo dos elementos. map, também, pode ou não retornar um valor. Em C ++ transform (o equivalente para map aqui) acontece para retornar uma iteração para a extremidade do recipiente de saída (recolha). Em Ruby, o valor de retorno da map é a sequência de saída (recolha). Assim, o valor de retorno dos algoritmos é realmente um detalhe de implementação; seu efeito pode ou não ser o que eles retornam.

Array.protototype.map método & Array.protototype.forEach ambas bastante similar.

Executar o seguinte 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));
});

Eles dão o resultado ditto exato.

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

Mas a reviravolta vem quando você executar o seguinte código: -

Aqui eu simplesmente atribuído o resultado do valor de retorno a partir do mapa e 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();

Agora, o resultado é algo complicado!

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

Conclusão

Array.prototype.map retorna uma matriz, mas Array.prototype.forEach não. Então você pode manipular a matriz retornada dentro da função callback passado para o método mapa e, em seguida, devolvê-lo.

Array.prototype.forEach única anda através da matriz dada para que você possa fazer suas coisas enquanto caminhava a matriz.

A diferença mais 'visível' é que o mapa acumula o resultado em uma nova coleção, enquanto foreach é feito apenas para a própria execução.

mas há um par de pressupostos extras: uma vez que o 'propósito' de mapa é a nova lista de valores, isso realmente não importa a ordem de execução. De fato, alguns ambientes de execução gerar código paralelo, ou mesmo introduzir algum memoizing para evitar chamar para valores repetidos, ou preguiça, para evitar chamar alguns em tudo.

foreach, por outro lado, é chamado especificamente para os efeitos secundários; portanto, a ordem é importante, e geralmente não podem ser paralelizado.

Resposta curta: map e forEach são diferentes. Além disso, informalmente falando, map é um super rigoroso de forEach.

Resposta longa: Primeiro, vamos chegar a um descrições de linha de forEach e map:

  • itera forEach mais de todos os elementos, chamando a função fornecida em cada um.
  • itera map mais de todos os elementos, chamando a função fornecida em cada um, e produz uma matriz transformado por lembrar o resultado de cada chamada de função.

Em muitas línguas, forEach é muitas vezes chamado apenas each. A discussão a seguir usa JavaScript apenas para referência. Ele poderia realmente ser qualquer outra língua.

Agora, vamos usar cada uma dessas funções.

Usando forEach:

Tarefa 1:. Escrever um printSquares função, que aceita uma matriz de números arr, e imprime o quadrado de cada um dos elementos em que

Solução 1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

Usando map:

Tarefa 2:. Escrever um selfDot função, que aceita uma matriz de números arr, e retorna uma matriz em que cada elemento é o quadrado do elemento correspondente em arr

Além: Aqui, em termos de gíria, estamos tentando fazer a quadratura do array de entrada. Formalmente colocar, estamos a tentar calculá-lo de produto escalar com ele mesmo.

Solução 2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

Como é map um super conjunto de forEach?

Você pode usar map para resolver as duas tarefas, Tarefa 1 e Tarefa 2 . No entanto, você não pode usar forEach para resolver o Tarefa 2 .

Em Solução 1 , se você simplesmente substituir forEach por map, a solução ainda será válido. Em Solução 2 no entanto, substituindo map por forEach vai quebrar a sua solução previamente funcionando.

Implementar forEach em termos de map:

Outra forma de perceber a superioridade do map é implementar forEach em termos de map. Como somos bons programadores, vamos não vai entrar em poluição namespace. Vamos chamar nosso forEach, apenas each.

Array.prototype.each = function (func) {
    this.map(func);
};

Agora, se você não gosta do absurdo prototype, aqui vai:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};

Então, umm .. Por do que forEach ainda existe?

A resposta é eficiência. Se você não está interessado em transformar um array para outro array, por que você deve calcular a matriz transformada? Só para despejá-lo? Claro que não! Se você não quer uma transformação, você não deve fazer uma transformação.

Assim, enquanto mapa pode ser usado para resolver Tarefa 1 , ele provavelmente não deveria. Para cada um é o candidato certo para isso.


resposta Original:

Enquanto eu concordam amplamente com @madlep 's resposta, eu gostaria de salientar que map() é um estrita super-set de forEach().

Sim, map() é geralmente usado para criar uma nova matriz. No entanto, pode também ser usado para alterar a matriz atual.

Aqui está um exemplo:

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!!"]

No exemplo acima, a foi convenientemente fixado de tal modo que a[i] === i para i < a.length. Mesmo assim, ele demonstra o poder da map().

Aqui está a descrição oficial de map() . Note-se que map() pode até mudar a matriz em que é chamado! Hail map().

Espero que isso ajudou.


Editado 10-Nov-2015:. Elaboração Adicionado

Aqui está um exemplo em Scala usando listas: mapa lista de retornos, foreach não retorna nada.

def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit

Assim mapear retorna a lista resultante da aplicação da função f para cada elemento da 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 apenas se aplica f a cada elemento:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty

Se você está falando de Javascript em particular, a diferença é que map é uma função loop while forEach é um iterador.

Use map quando você deseja aplicar uma operação para cada membro da lista e obter os resultados de volta como uma nova lista, sem afetar a lista original.

Use forEach quando você quiser do algo na base de cada elemento da lista. Você pode estar adicionando coisas para a página, por exemplo. Essencialmente, é ótimo para quando você quiser "efeitos colaterais".

Outras diferenças: forEach retorna nada (uma vez que é realmente uma função de controle de fluxo), eo passou-in função obtém referências para o índice e toda a lista, enquanto mapa regressa a nova lista e só passa no elemento atual.

ForEach tenta aplicar uma função, como escrevendo para db etc em cada elemento do RDD sem retornar nada de volta.

Mas o map() aplica alguma função sobre os elementos da RDD e retorna o RDD. Então, quando você executar o abaixo método não irá falhar em line3 mas ao coletar o RDD após a aplicação foreach ele vai falhar e lançar um erro que diz

File "", linha 5, em

AttributeError: objeto 'NoneType' tem nenhum atributo 'cobrar'

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())
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top