Це додаткова відповідь, яка допоможе пояснити карти та складки. Для наведених нижче прикладів я буду використовувати цей список. Пам'ятайте, що цей список незмінний, тому він ніколи не зміниться:
var numbers = [1, 2, 3, 4, 5]
Я буду використовувати цифри у своїх прикладах, оскільки вони призводять до легкого для читання коду. Пам’ятайте, однак, складки можуть бути використані для чого завгодно, для чого можна використовувати традиційний імперативний цикл.
Карта приймає список чого - або, і функцію, і повертає список , який був модифікований з допомогою функції. Кожен елемент передається функції та стає тим, що функція повертається.
Найпростіший приклад цього - просто додати число до кожного номера у списку. Я буду використовувати псевдокод, щоб зробити його агностичним:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Якби ви надрукували numbers2
, ви побачили б, [3, 4, 5, 6, 7]
який перший список із 2-ма доданими до кожного елемента. Зверніть увагу, функція add-two
була надана map
для використання.
Папки складаються аналогічно, за винятком функції, яку вам потрібно надати, потрібно взяти 2 аргументи. Перший аргумент - це зазвичай акумулятор (у лівій складці, які є найпоширенішими). Акумулятор - це дані, передані під час циклу. Другий аргумент - це поточний пункт списку; як і вище для map
функції.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Якщо ви надрукували, sum
ви побачили б суму списку чисел: 15.
Ось які аргументи потрібно fold
зробити:
Це функція, яку ми надаємо складці. Згинання передасть функцію акумулятора струму та поточного елемента списку. Незалежно від функції, яка повертається, стане новим акумулятором, який буде переданий функції наступного разу. Ось так ви «запам’ятовуєте» значення, коли ви циклічно використовуєте FP-стиль. Я дав йому функцію, яка бере 2 числа і додає їх.
Це початковий акумулятор; що запускає акумулятор, як і раніше, ніж будь-які елементи у списку обробляються. Коли ви підсумовуєте числа, яка загальна сума, перш ніж ви додали будь-які цифри разом? 0, який я передав як другий аргумент.
Нарешті, як і з картою, ми також передаємо список номерів для її обробки.
Якщо складки все ще не мають сенсу, врахуйте це. Коли ви пишете:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Ви в основному поміщаєте передану функцію між кожним елементом у списку та додаєте початковий акумулятор або вліво, або вправо (залежно від того, чи це ліва чи права частина), так:
[1, 2, 3, 4, 5]
Стає:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Що дорівнює 15.
Використовуйте, map
коли ви хочете перетворити один список в інший, однакової довжини.
Використовуйте, fold
коли ви хочете перетворити список в єдине значення, наприклад підсумовуючи список чисел.
Як зазначав @Jorg в коментарях, "єдине значення" не повинно бути чимось простим, як число; це може бути будь-який єдиний об'єкт, включаючи список або кортеж! Те, як я насправді мав складки, для мене полягав у визначенні карти з точки зору складки. Зверніть увагу, як складається аккумулятор у списку:
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)
Чесно кажучи, щойно ви зрозумієте кожен, ви зрозумієте, що практично будь-яке циклічне змінення може бути замінено складкою або картою.