Truyền hàm
Thuộc phần Logic và luồng điều khiển trong hành trình R của Coddy. Bài học 28 trên 64.
Một hàm có thể nhận một hàm khác làm đối số rồi gọi hàm đó. apply_twice() bên dưới hoạt động với mọi hàm có một tham số:
apply_twice <- function(f, x) f(f(x))
print(apply_twice(\(x) x + 3, 10))
print(apply_twice(toupper, "ok"))Đầu ra:
[1] 16
[1] "OK"Các hàm dựng sẵn như sum, max hoặc toupper cũng là giá trị, vì vậy hãy truyền chúng bằng tên mà không có dấu ngoặc đơn. Nếu có dấu ngoặc đơn, chúng sẽ được gọi thay vì:
summarize <- function(xs, how) how(xs)
print(summarize(c(4, 9, 2), max))
print(summarize(c(4, 9, 2), sum))Đầu ra:
[1] 9
[1] 15Một hàm nhận vào một điều kiện kiểm tra, tức là một hàm trả về TRUE hoặc FALSE, có thể đếm hoặc chọn giá trị theo bất kỳ quy tắc nào:
count_if <- function(xs, keep) {
n <- 0
for (x in xs) if (keep(x)) n <- n + 1
n
}
print(count_if(c(3, 8, 10, 5), \(x) x %% 2 == 0))
print(count_if(c(3, 8, 10, 5), \(x) x > 4))Đầu ra:
[1] 2
[1] 3Bên gọi quyết định hành vi, còn hàm cung cấp vòng lặp, vì vậy một hàm có thể xử lý nhiều trường hợp:
transform_each <- function(xs, f) {
out <- c()
for (x in xs) out <- c(out, f(x))
out
}
print(transform_each(1:4, \(x) x * 10))
print(transform_each(c("a", "b"), toupper))Đầu ra:
[1] 10 20 30 40
[1] "A" "B"Thử thách
DễHoàn thiện apply_n(f, x, n). Gọi f với x, rồi gọi với kết quả đó, tổng cộng n lần, và trả về giá trị cuối cùng. Khi n bằng 0, trả về x không thay đổi.
Code được cung cấp định nghĩa ba hàm, double, inc và half. Code đọc tên của một trong các hàm đó, giá trị bắt đầu và n, rồi in ra kết quả của apply_n().
Tự làm thử
apply_n <- function(f, x, n) {
# Viết code của bạn ở đây
x
}
# Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
ops <- list(double = \(x) x * 2, inc = \(x) x + 1, half = \(x) x / 2)
cat(apply_n(ops[[input[1]]], as.numeric(input[2]), as.numeric(input[3])), sep = "\n")
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Chuỗi chuyên sâu
Chuỗi con với substr()Định dạng với sprintf()Tách và nối chuỗiTìm kiếm trong chuỗiThay thế văn bảnÔn tập: Tạo tên người dùng10Luồng điều khiển nâng cao
Hàm switch()ifelse() dạng vector hóarepeat và breakHàm đệ quyÔn tập: phân loại điểmTự luyện tập: Trình biên dịch R online