Песочница

Работа с map, filter, fold и apply

Выбирайте map для преобразования элементов, filter для отбора и свёртку для объединения в один результат.

Используйте filter для отбора элементов, map для их преобразования и свёртку для получения одного общего результата. В этом примере программа складывает квадраты нечётных чисел из списка.

Отберите, преобразуйте и сложите

Запустите этот полный пример на площадке.

LISPEX
(reduce + 0 (map (lambda (x) (* x x)) (filter odd? (list 1 2 3 4))))

Результат

ВЫВОД
10

Читайте вложенные вызовы изнутри наружу.

  1. filter оставляет 1 и 3: для них odd? возвращает #t.
  2. map возводит эти элементы в квадрат и получает (1 9).
  3. reduce начинает с 0, складывает квадраты и получает 10.

Каждая из этих процедур принимает другую процедуру как аргумент. Поэтому её называют процедурой высшего порядка. Переданную процедуру, которую вызывают для каждого элемента, часто называют процедурой обратного вызова.

Выберите нужный результат

ЗадачаПроцедура
Получить по одному преобразованному элементу для каждого исходногоmap; для строк — string-map, для векторов — vector-map
Оставить элементы, прошедшие проверкуfilter
Накопить один результат из всех элементовreduce или её псевдоним fold-left; для обхода справа — fold-right
Проверить, все ли элементы или хотя бы один проходят проверкуall? или any?; обход прекращается, как только ответ известен
Выполнить действие для каждого элемента, например напечатать егоfor-each, string-for-each или vector-for-each

Процедуры обхода принимают один список, строку или вектор. Аргументы и возвращаемые значения каждого вызова приведены в справочнике.

Передайте аргументы из списка через apply

Используйте apply, чтобы один раз вызвать процедуру с аргументами, сохранёнными в списке.

LISPEX
(apply + 1 (list 2 3))

Результат

ВЫВОД
6

Этот код вызывает + с аргументами 1, 2 и 3. Элементы последнего списка добавляются после аргументов, указанных перед ним.

Найдите место для исправления

Ошибка E302 означает неверное число аргументов. Проверьте и внешний вызов, и переданную ему процедуру. Например, map передаёт по одному элементу, а reduce — накопленный результат и элемент.

Ошибка E320 означает, что вызов вернул ноль или несколько значений там, где нужно одно. Если вы передали display в map, используйте для печати for-each. Если нужен новый список, исправьте переданную в map процедуру так, чтобы она возвращала по одному значению на элемент.

В справочнике по процедурам высшего порядка эти требования собраны вместе. Сопоставьте их с вызовом, который завершился ошибкой.

Попробуйте изменить пример

Что вернёт первый пример, если заменить odd? на even??

Ответ

Он оставит 2 и 4, возведёт их в квадрат, получив (4 16), и вернёт 20.

Используйте рекурсию, когда нужно самостоятельно управлять обходом.