Используйте filter для отбора элементов, map для их преобразования и свёртку для получения одного общего результата. В этом примере программа складывает квадраты нечётных чисел из списка.
Отберите, преобразуйте и сложите
Запустите этот полный пример на площадке.
(reduce + 0 (map (lambda (x) (* x x)) (filter odd? (list 1 2 3 4))))Результат
10Читайте вложенные вызовы изнутри наружу.
filterоставляет1и3: для нихodd?возвращает#t.mapвозводит эти элементы в квадрат и получает(1 9).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, чтобы один раз вызвать процедуру с аргументами, сохранёнными в списке.
(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.
Используйте рекурсию, когда нужно самостоятельно управлять обходом.