Menu
CoddyTech

Trả về 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 29 trên 64.

Một hàm cũng có thể trả về một hàm. make_multiplier(3) trả về một hàm mới nhân đối số của hàm đó với 3:

make_multiplier <- function(n) {
  function(x) x * n
}
triple <- make_multiplier(3)
print(triple(5))
print(make_multiplier(10)(5))

Đầu ra:

[1] 15
[1] 50

Hàm được trả về ghi nhớ các giá trị mà nó được tạo cùng. Sự kết hợp giữa một hàm và các biến xung quanh nó được gọi là bao đóng. Mỗi lần gọi hàm tạo sẽ tạo ra một bao đóng riêng:

make_greeter <- function(greeting) {
  function(name) paste0(greeting, ", ", name, "!")
}
hello <- make_greeter("Hello")
hola <- make_greeter("Hola")
print(hello("Ada"))
print(hola("Ada"))

Đầu ra:

[1] "Hello, Ada!"
[1] "Hola, Ada!"

Hàm tạo biến một vài thiết lập thành một công cụ có sẵn, chẳng hạn như công cụ chuyển đổi giữa các đơn vị:

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))

Đầu ra:

[1] 212
[1] 6.21

Có thể kết hợp các hàm thành hàm mới. compose(f, g) trả về một hàm chạy f rồi đến g:

compose <- function(f, g) function(x) g(f(x))
clean <- compose(trimws, toupper)
print(clean("  hi there "))

Đầu ra:

[1] "HI THERE"
challenge icon

Thử thách

Dễ

Hoàn thiện make_formatter(prefix, digits). Hàm này trả về một hàm nhận vào một số và trả về prefix theo sau là số đó với digits chữ số thập phân: make_formatter("$", 2)(3.5) trả về $3.50.

sprintf("%.*f", digits, x) định dạng x với digits chữ số thập phân.

Code được cung cấp đọc tiền tố, số chữ số thập phân và danh sách các số được phân tách bằng dấu phẩy. Code này tạo một hàm định dạng rồi in ra kết quả của hàm đó cho từng số.

Tự làm thử

make_formatter <- function(prefix, digits) {
  # Viết code của bạn ở đây
  function(x) ""
}

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
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 = "")
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch R online