To jest dodatkowa odpowiedź, która pomaga wyjaśnić mapy i fałdy. W poniższych przykładach użyję tej listy. Pamiętaj, że ta lista jest niezmienna, więc nigdy się nie zmieni:
var numbers = [1, 2, 3, 4, 5]
Użyję liczb w moich przykładach, ponieważ prowadzą one do łatwego do odczytania kodu. Pamiętaj jednak, że fałdy mogą być używane do wszystkiego, do czego może być używana tradycyjna pętla imperatywna.
mapa pobiera listę coś i funkcję i zwraca listę, która została zmodyfikowana za pomocą funkcji. Każdy element jest przekazywany do funkcji i staje się tym, co funkcja zwraca.
Najłatwiejszym tego przykładem jest dodanie numeru do każdego numeru na liście. Użyję pseudokodu, aby był niezależny od języka:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Jeśli wydrukowałeś numbers2
, zobaczysz, [3, 4, 5, 6, 7]
która jest pierwsza lista z 2 dodanymi do każdego elementu. Zauważ, że funkcja add-two
została przekazanamap
użyta.
Fold s są podobne, z tym wyjątkiem, że funkcja, którą musisz im nadać, musi przyjąć 2 argumenty. Pierwszym argumentem jest zwykle akumulator (w lewej części, które są najczęściej). Akumulator to dane przekazywane w pętli. Drugi argument to bieżący element listy; podobnie jak powyżej dla map
funkcji.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Jeśli wydrukowałeś sum
, zobaczysz sumę listy liczb: 15.
Oto argumenty do fold
zrobienia:
Jest to funkcja, którą dajemy fold. W folderze przejdzie funkcja bieżącego akumulatora i bieżąca pozycja na liście. Cokolwiek zwróci funkcja, stanie się nowym akumulatorem, który zostanie przekazany do funkcji następnym razem. W ten sposób „zapamiętujesz” wartości, gdy zapętlasz styl FP. Dałem mu funkcję, która pobiera 2 liczby i dodaje je.
To jest akumulator początkowy; co akumulator zaczyna, jak przed przetworzeniem jakichkolwiek pozycji na liście. Kiedy sumujesz liczby, jaka jest suma, zanim dodasz jakieś liczby razem? 0, które podałem jako drugi argument.
Wreszcie, podobnie jak w przypadku mapy, przekazujemy również listę liczb do przetworzenia.
Jeśli fałdy nadal nie mają sensu, rozważ to. Kiedy piszesz:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Zasadniczo umieszczasz przekazaną funkcję między każdą pozycją na liście i dodajesz akumulator początkowy do lewej lub prawej (w zależności od tego, czy jest to lewy czy prawy pas), więc:
[1, 2, 3, 4, 5]
Staje się:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Co równa się 15.
Użyj a, map
jeśli chcesz zamienić jedną listę na inną, o tej samej długości.
Użyj a, fold
gdy chcesz zmienić listę w pojedynczą wartość, na przykład sumując listę liczb.
Jak zauważył @Jorg w komentarzach, „pojedyncza wartość” nie musi być czymś prostym jak liczba; może to być dowolny pojedynczy obiekt, w tym lista lub krotka! Sposób, w jaki faktycznie kliknąłem dla siebie foldery, polegał na zdefiniowaniu mapy w kategoriach fold. Zwróć uwagę, jak akumulator jest listą:
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)
Szczerze mówiąc, kiedy zrozumiesz każdy, zdasz sobie sprawę, że prawie każdą pętlę można zastąpić fałdem lub mapą.