Questa è una risposta supplementare per aiutare a spiegare mappe e pieghe. Per gli esempi seguenti, userò questo elenco. Ricorda, questo elenco è immutabile, quindi non cambierà mai:
var numbers = [1, 2, 3, 4, 5]
Userò i numeri nei miei esempi perché portano a un codice di facile lettura. Ricorda, tuttavia, le pieghe possono essere utilizzate per qualsiasi cosa per cui si possa usare un ciclo imperativo tradizionale.
Una mappa prende un elenco di qualcosa e una funzione e restituisce un elenco che è stato modificato utilizzando la funzione. Ogni elemento viene passato alla funzione e diventa qualunque cosa restituisca la funzione.
L'esempio più semplice di ciò è semplicemente l'aggiunta di un numero a ciascun numero in un elenco. Userò lo pseudocodice per rendere agnostico il linguaggio:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Se stampassi numbers2
, vedresti [3, 4, 5, 6, 7]
quale è il primo elenco con 2 aggiunti a ciascun elemento. Si noti che è add-two
stata assegnata la funzione map
da utilizzare.
Le piegature sono simili, ad eccezione della funzione richiesta per assegnarle che deve accettare 2 argomenti. Il primo argomento è di solito l'accumulatore (in una piega a sinistra, che sono i più comuni). L'accumulatore sono i dati passati durante il ciclo. Il secondo argomento è l'elemento corrente dell'elenco; proprio come sopra per la map
funzione.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Se stampassi sum
vedresti la somma dell'elenco dei numeri: 15.
Ecco cosa devono fold
fare gli argomenti :
Questa è la funzione che stiamo offrendo. La piega passerà la funzione dell'accumulatore corrente e l'elemento corrente dell'elenco. Qualunque sia la funzione restituita diventerà il nuovo accumulatore, che verrà passato alla funzione la volta successiva. Ecco come "ricordi" i valori quando esegui il looping in stile FP. Gli ho dato una funzione che accetta 2 numeri e li aggiunge.
Questo è l'accumulatore iniziale; come inizia l'accumulatore prima che vengano elaborati tutti gli elementi nell'elenco. Quando sommi i numeri, qual è il totale prima di aver aggiunto tutti i numeri? 0, che ho passato come secondo argomento.
Infine, come per la mappa, passiamo anche nell'elenco dei numeri per l'elaborazione.
Se le pieghe non hanno ancora senso, considera questo. Quando scrivi:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
In pratica stai mettendo la funzione passata tra ciascun elemento nell'elenco e aggiungi l'accumulatore iniziale a sinistra oa destra (a seconda che si tratti di una piega sinistra o destra), quindi:
[1, 2, 3, 4, 5]
diventa:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Che equivale a 15.
Utilizzare a map
quando si desidera trasformare un elenco in un altro elenco, della stessa lunghezza.
Usa a fold
quando vuoi trasformare un elenco in un singolo valore, come sommare un elenco di numeri.
Come ha sottolineato @Jorg nei commenti, il "valore singolo" non deve necessariamente essere qualcosa di semplice come un numero; potrebbe essere un singolo oggetto, incluso un elenco o una tupla! Il modo in cui ho effettivamente fatto clic sulle pieghe per me era definire una mappa in termini di piega. Nota come l'accumulatore è un elenco:
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
Onestamente, una volta capiti tutti, ti renderai conto che quasi tutti i loop possono essere sostituiti da una piega o una mappa.