Domanda

Ok, questa è più una questione informatica, che una domanda basata su un linguaggio particolare, ma c'è differenza tra un'operazione map e un'operazione foreach?O sono semplicemente nomi diversi per la stessa cosa?

È stato utile?

Soluzione

differenti.

itera foreach su un elenco e applica qualche operazione con effetti collaterali a ciascun membro (come il salvataggio ciascuno al database per esempio)

mappa itera su un elenco, trasforma ogni membro di quella lista, e restituisce un altro elenco delle stesse dimensioni, con i membri trasformati (come la conversione di una lista di stringhe in maiuscolo)

Altri suggerimenti

La differenza importante tra loro è che map accumula tutti i risultati in una collezione, mentre foreach restituisce nulla. <=> di solito è usato quando si vuole trasformare una collezione di elementi con una funzione, mentre <=> semplicemente esegue un'azione per ogni elemento.

In breve, foreach serve per applicare un'operazione su ciascun elemento di una raccolta di elementi, mentre map serve per trasformare una collezione in un'altra.

Ci sono due differenze significative tra foreach E map.

  1. foreach non ha restrizioni concettuali sull'operazione che applica, a parte forse accettare un elemento come argomento.Cioè, l'operazione potrebbe non fare nulla, potrebbe avere un effetto collaterale, potrebbe restituire un valore o potrebbe non restituire un valore.Tutto foreach ciò che interessa è scorrere una raccolta di elementi e applicare l'operazione su ciascun elemento.

    map, invece, presenta una restrizione all'operazione:si aspetta che l'operazione restituisca un elemento e probabilmente accetti anche un elemento come argomento.IL map L'operazione esegue un'iterazione su una raccolta di elementi, applicando l'operazione a ciascun elemento e infine memorizzando il risultato di ogni invocazione dell'operazione in un'altra raccolta.In altre parole, il map trasforma una raccolta nell'altra.

  2. foreach funziona con una singola raccolta di elementi.Questa è la raccolta di input.

    map funziona con due raccolte di elementi:la raccolta degli input e la raccolta degli output.

Non è un errore mettere in relazione i due algoritmi:infatti, puoi visualizzarli gerarchicamente, dove map è una specializzazione di foreach.Cioè, potresti usare foreach e chiedi all'operazione di trasformare il suo argomento e inserirlo in un'altra raccolta.Così il foreach L'algoritmo è un'astrazione, una generalizzazione, del map algoritmo.In effetti, perché foreach non ha alcuna restrizione al suo funzionamento, possiamo tranquillamente dirlo foreach è il meccanismo di loop più semplice disponibile e può fare tutto ciò che può fare un loop. map, così come altri algoritmi più specializzati, è lì per l'espressività:se desideri mappare (o trasformare) una raccolta in un'altra, la tua intenzione è più chiara se usi map che se usi foreach.

Possiamo estendere ulteriormente questa discussione e considerare il copy algoritmo:un ciclo che clona una raccolta.Anche questo algoritmo è una specializzazione del foreach algoritmo.Potresti definire un'operazione che, dato un elemento, inserirà lo stesso elemento in un'altra raccolta.Se usi foreach con quell'operazione hai effettivamente eseguito il copy algoritmo, anche se con chiarezza, espressività o esplicitezza ridotte.Andiamo ancora oltre:Possiamo dirlo map è una specializzazione di copy, essa stessa una specializzazione di foreach. map Maggio modifica uno qualsiasi degli elementi su cui itera.Se map non cambia nessuno degli elementi, semplicemente copiato gli elementi e l'utilizzo copia esprimerebbe l'intento in modo più chiaro.

IL foreach l'algoritmo stesso può o meno avere un valore restituito, a seconda della lingua.In C++, ad esempio, foreach restituisce l'operazione ricevuta originariamente.L'idea è che l'operazione potrebbe avere uno stato e potresti volerla ripristinare per verificare come si è evoluta nel corso degli elementi. map, anche , può restituire o meno un valore.Nel C++ transform (l'equivalente di map qui) sembra restituire un iteratore alla fine del contenitore di output (raccolta).In Ruby, il valore restituito di map è la sequenza di output (raccolta).Quindi, il valore restituito dagli algoritmi è in realtà un dettaglio implementativo;il loro effetto può essere o meno quello che restituiscono.

metodo Array.protototype.map & Array.protototype.forEach sono entrambi molto simili.

Eseguire il seguente codice: 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));
});

Danno l'esatto risultato idem.

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

Ma il colpo di scena arriva quando si esegue il seguente codice: -

Qui ho semplicemente assegnato il risultato del valore di ritorno dalla mappa e foreach metodi.

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();

Ora il risultato è qualcosa di complicato!

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

Conclusione

Array.prototype.map restituisce un array, ma Array.prototype.forEach non lo fa. Così si può manipolare la matrice restituita all'interno della funzione di callback passato al metodo mappa e poi restituirlo.

<=> cammina solo attraverso l'array data in modo da poter fare le tue cose mentre si cammina la matrice.

La differenza più 'visibile' è quella mappa si accumula il risultato in una nuova collezione, mentre foreach è fatto soltanto per l'esecuzione stessa.

, ma ci sono un paio di ipotesi in più: dal momento che la 'fine' di carta è il nuovo elenco di valori, non importa in realtà l'ordine di esecuzione. infatti, alcuni ambienti di esecuzione generano codice parallelo, o anche introdurre qualche memoizing per evitare di chiamare per valori ripetuti, o pigrizia, per evitare di chiamare un po 'a tutti.

foreach, invece, è chiamato specificamente per gli effetti collaterali; quindi l'ordine è importante, e di solito non può essere parallelised.

Risposta breve: e map forEach sono diversi. Inoltre, in modo informale parlando, each è un superset di stretta printSquares.

Risposta lunga: Per prima cosa, venire con una descrizione di linea di arr e selfDot:

  • prototype itera su tutti gli elementi, chiamando la funzione in dotazione su ciascuno.
  • map() itera su tutti gli elementi, chiamando la funzione fornito su ciascuno, e produce un vettore trasformato ricordando il risultato di ogni chiamata di funzione.

In molte lingue, forEach() è spesso chiamato semplicemente a. La seguente discussione utilizza JavaScript solo per riferimento. Potrebbe davvero essere una qualsiasi altra lingua.

Ora, proviamo ad utilizzare ciascuna di queste funzioni.

Uso a[i] === i:

Task 1: scriva una funzione i < a.length, che accetta una matrice di numeri <=>, e stampa il quadrato di ciascun elemento in esso

.

Soluzione 1:

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

Uso <=>:

Procedura 2:. scriva una funzione <=>, che accetta una matrice di numeri <=>, e restituisce una matrice in cui ciascun elemento è il quadrato della corrispondente elemento <=>

A parte: Qui, in termini slang, stiamo cercando di quadrare l'array di input. Formalmente messo, stiamo cercando di calcolare è prodotto scalare con se stesso.

Soluzione 2:

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

Come è <=> un superset di <=>?

È possibile utilizzare <=> per risolvere entrambi i compiti, Task 1 e Task 2 . Tuttavia, non è possibile utilizzare <=> per risolvere il Task 2 .

Nel Soluzione 1 , se si sostituisce semplicemente <=> dal <=>, la soluzione sarà ancora valida. In Soluzione 2 tuttavia, sostituendo <=> da <=> si romperà la vostra soluzione in precedenza lavoro.

L'implementazione <=> in termini di <=>:

Un altro modo di realizzare la superiorità <=> s 'è quello di implementare <=> in termini di <=>. Dato che siamo buoni programmatori, ci Non indulgere in inquinamento dello spazio dei nomi. Chiameremo i nostri <=>, basta <=>.

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

Ora, se non ti piace il <=> sciocchezze, qui si va:

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

Così, umm .. Perché di fa <=> ancora esiste?

La risposta è l'efficienza. Se non siete interessati a trasformare un array in un altro array, perché si dovrebbe calcolare il vettore trasformato? Solo a discarica? Ovviamente no! Se non si desidera una trasformazione, non si deve fare una trasformazione.

Così, mentre mappa può essere utilizzato per risolvere Task 1 , probabilmente non dovrebbe. Per ciascuno è il candidato giusto per farlo.


risposta originale:

Mentre in gran parte d'accordo con la risposta s' @madlep, vorrei far notare che <=> è un rigoroso super-set di <=>.

Sì, <=> di solito è usato per creare un nuovo array. Tuttavia, esso può anche essere usato per modificare la matrice corrente.

Ecco un esempio:

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

Nell'esempio precedente, <=> è comodamente impostata in modo tale che <=> per <=>. Anche così, dimostra la potenza di <=>.

Ecco la descrizione ufficiale di <=> . Si noti che <=> può anche cambiare la matrice su cui è chiamata! Salve <=>.

Spero che questo ha aiutato.


A cura 10-Nov-2015:. Elaborazione Aggiunto

Ecco un esempio in Scala utilizzando gli elenchi: mappa ritorna lista, foreach non restituisce nulla.

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

Quindi mappa restituisce la lista risultante dall'applicazione della funzione f ad ogni elemento della 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 si applica solo f per ogni elemento:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

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

Se si sta parlando di JavaScript in particolare, la differenza è che map è una funzione ciclo while forEach è un iteratore.

Utilizzare <=> quando si desidera applicare un'operazione per ciascun membro della lista e ottenere i risultati indietro come un nuovo elenco, senza modificare l'elenco originale.

Utilizzare <=> quando si desidera do qualcosa sulla base di ogni elemento della lista. Si potrebbe aggiungere cose alla pagina, per esempio. In sostanza, è grande per quando si vuole "effetti collaterali".

Altre differenze: <=> restituisce nulla (dal momento che è in realtà una funzione del flusso di controllo), e la funzione passata in ottiene riferimenti al indice e l'intera lista, mentre mappa restituisce il nuovo elenco e solo passa nella corrente elemento.

ForEach cerca di applicare una funzione come la scrittura db ecc su ogni elemento della RDD senza restituire nulla in cambio.

Ma la map() applica una qualche funzione nel corso degli elementi di RDD e restituisce il RDD. Così, quando si esegue il metodo seguito non mancherà a line3 ma, mentre la raccolta del RDD dopo l'applicazione foreach fallirà e genera un errore che dice

  

File "", la linea 5, in

     

AttributeError: oggetto 'NoneType' non ha alcun attributo 'raccogliere'

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())
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top