Menu
CoddyTech

Hàm nhận số lượng đối số linh hoạt (...)

Thuộc phần Logic và luồng chương trình trong hành trình Lua của Coddy. Bài học 11 trên 54.

Đôi khi bạn cần một hàm có thể xử lý bất kỳ số lượng đối số nào. Có thể bạn muốn tính tổng của hai, ba hoặc mười số mà không cần viết hàm riêng cho từng trường hợp. Lua cung cấp cú pháp đặc biệt cho việc này: ba dấu chấm ...

Khi đặt ... trong danh sách tham số của một hàm, bạn sẽ tạo ra một hàm biến thiên có thể nhận bất kỳ số lượng đối số nào:

function sum(...)
    -- Thân hàm
end

Bên trong hàm, bạn có thể truy cập các đối số này bằng cách dùng lại .... Để làm việc với chúng dễ dàng hơn, bạn có thể gói chúng vào một bảng bằng cách dùng dấu ngoặc nhọn:

function sum(...)
    local args = {...}
    local total = 0
    for i = 1, #args do
        total = total + args[i]
    end
    return total
end

print(sum(5, 10, 15))  -- Đầu ra: 30
print(sum(1, 2, 3, 4, 5))  -- Đầu ra: 15

Biểu thức {...} tạo một bảng kiểu danh sách chứa tất cả đối số được truyền cho hàm. Sau đó, bạn có thể lặp qua bảng này như mọi bảng khác, bằng cách dùng toán tử độ dài # hoặc ipairs().

Cách này hoạt động miễn là không có đối số nào là nil. Giá trị nil tạo ra khoảng trống trong bảng, và # không đáng tin cậy với bảng có khoảng trống. select("#", ...) luôn trả về số lượng đối số, kể cả những đối số nil:

function countArgs(...)
    return select("#", ...)
end

print(countArgs(10, 20, 30))        -- Đầu ra: 3
print(countArgs(10, nil, 30, nil))  -- Đầu ra: 4
challenge icon

Thử thách

Dễ

Viết một hàm calculateAverage nhận bất kỳ số lượng đối số dạng số nào và trả về giá trị trung bình của chúng.

Dùng cú pháp biến đối ... để nhận số lượng đối số linh hoạt, gói chúng vào một bảng, tính tổng rồi chia cho số lượng đối số.

Lưu ý: Code khởi đầu (được đánh dấu "Don't touch this code") đọc các số từ đầu vào, chuyển từng giá trị từ văn bản thành số bằng tonumber() và lưu chúng vào một bảng có tên numbers. Cuối cùng, code gọi hàm của bạn bằng unpack(numbers), thao tác này truyền từng giá trị trong bảng dưới dạng đối số riêng lẻ, vì vậy hàm của bạn nhận chúng qua .... Bạn không cần chỉnh sửa hoặc hiểu chi tiết đoạn code này, chỉ cần tập trung viết calculateAverage.

Logic:

  • Gói tất cả đối số vào một bảng bằng {...}
  • Lặp qua bảng để tính tổng tất cả các số
  • Chia tổng cho số lượng đối số để tính giá trị trung bình
  • Trả về giá trị trung bình dưới dạng số

Tham số:

  • ... (các số): Số lượng đối số dạng số linh hoạt

Giá trị trả về: Giá trị trung bình của tất cả các số đã cho (số)

Tự làm thử

-- Đừng sửa đoạn code này --
local numbers = {}
while true do
    local input = io.read()
    if input == nil or input == "" then
        break
    end
    local num = tonumber(input)
    if num then
        table.insert(numbers, num)
    end
end
-------------------------

function calculateAverage(...)
    -- Viết code ở đây
end
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 chương trình

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