Возврат функций
Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 29 из 64.
Функция также может возвращать функцию. make_multiplier(3) возвращает новую функцию, которая умножает свой аргумент на 3:
make_multiplier <- function(n) {
function(x) x * n
}
triple <- make_multiplier(3)
print(triple(5))
print(make_multiplier(10)(5))Вывод:
[1] 15
[1] 50Возвращаемая функция запоминает значения, с которыми она была создана. Это сочетание функции и окружающих её переменных называется замыканием. Каждый вызов функции-фабрики создаёт отдельное замыкание:
make_greeter <- function(greeting) {
function(name) paste0(greeting, ", ", name, "!")
}
hello <- make_greeter("Hello")
hola <- make_greeter("Hola")
print(hello("Ada"))
print(hola("Ada"))Вывод:
[1] "Hello, Ada!"
[1] "Hola, Ada!"Функция-создатель превращает несколько настроек в готовый инструмент, например конвертер между единицами измерения:
make_converter <- function(factor, offset = 0) {
function(x) x * factor + offset
}
c_to_f <- make_converter(1.8, 32)
km_to_miles <- make_converter(0.621)
print(c_to_f(100))
print(km_to_miles(10))Результат:
[1] 212
[1] 6.21Функции можно объединять в новые функции. compose(f, g) возвращает функцию, которая сначала выполняет f, а затем g:
compose <- function(f, g) function(x) g(f(x))
clean <- compose(trimws, toupper)
print(clean(" hi there "))Результат:
[1] "HI THERE"Задание
ЛегкоРеализуйте make_formatter(prefix, digits). Она возвращает функцию, которая принимает число и возвращает prefix, за которым следует число с digits знаками после запятой: make_formatter("$", 2)(3.5) возвращает $3.50.
sprintf("%.*f", digits, x) форматирует x, используя digits знаков после запятой.
Предоставленный код считывает префикс, количество знаков после запятой и список чисел, разделённых запятыми. Он создаёт один форматировщик и выводит его результат для каждого числа.
Попробуйте сами
make_formatter <- function(prefix, digits) {
# Напишите свой код здесь
function(x) ""
}
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
fmt <- make_formatter(input[1], as.integer(input[2]))
for (x in as.numeric(strsplit(input[3], ",")[[1]])) cat(fmt(x), "\n", sep = "")
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и потоки выполнения
1Строки углублённо
Подстроки с substr()Форматирование с sprintf()Разделение и объединениеПоиск в строкахЗамена текстаПовторение — создание имени пользователя4Матрицы
Создание матрицИндексация матрицСводные данные по строкам и столбцамАрифметика матрицПовторение — схема рассадки7Семейство Apply
lapply и sapplyMap и mapplyFilter и FindReduceПовторение — конвейер обработки данных10Продвинутые конструкции управления
Функция switch()Векторизованный ifelse()repeat и breakРекурсивные функцииПовторение — классификатор оценок2Поиск по ключам и значениям
Поиск в именованных векторахПроверка ключейДобавление и удаление ключейПеребор имёнПовторение — биржа акций5Проект — Журнал оценок
Добавление учениковВыставление оценок3Множества и подсчёт
Уникальные значенияОперации с множествамиПроверка принадлежностиПодсчёт с помощью table()Повторение — гости мероприятия6Функции как значения
Анонимные функцииПередача функцийВозврат функцийЗамыкания с состояниемПовторение — правила скидок9Таблицы данных
Создание таблиц данныхСтолбцы и строкиФильтрация строкДобавление и сортировкаПовторение — отчёт о продажах12Проект — Трекер расходов
Запись расходовОбщие расходыПотренируйтесь самостоятельно: Онлайн-компилятор R