reduce / inject
Thuộc phần Logic và luồng xử lý trong hành trình Ruby của Coddy. Bài học 23 trên 56.
Đôi khi bạn cần rút gọn cả một mảng thành một giá trị duy nhất, chẳng hạn như tổng, tích hoặc chuỗi dài nhất. reduce (còn gọi là inject: cùng một phương thức, hai tên gọi) là công cụ để làm việc đó.
Khối lệnh nhận hai tham số: bộ tích lũy (accumulator) và phần tử hiện tại. Giá trị trả về của khối lệnh trở thành bộ tích lũy tiếp theo.
total = [1, 2, 3, 4].reduce(0) { |acc, n| acc + n }
puts total # 10Lần lượt, giá trị của biến tích lũy là 0 → 1 → 3 → 6 → 10.
Đối số đầu tiên là giá trị bắt đầu của biến tích lũy. Nếu bạn bỏ qua đối số này, Ruby sẽ dùng phần tử đầu tiên của mảng:
[1, 2, 3, 4].reduce { |acc, n| acc * n } # 24Với các phép toán thuần túy như cộng và nhân, Ruby có cách viết tắt: truyền một symbol thay vì một block:
[1, 2, 3, 4].reduce(:+) # 10
[1, 2, 3, 4].reduce(:*) # 24Khi đã biết cách tạo một bộ tích lũy tùy chỉnh, bạn có thể tính gần như mọi thứ chỉ trong một lượt duyệt.
Thử thách
DễĐọc một danh sách số nguyên được phân tách bằng dấu phẩy. In ra ba dòng:
- Tổng (dùng
reduce(:+)) - Tích (dùng
reduce(:*)) - Giá trị lớn nhất, được tính bằng
reducevới một khối lệnh tường minh, không dùngmax.
Với đầu vào 2,5,3,8, đầu ra là:
18
240
8Tự làm thử
numbers = gets.chomp.split(",").map(&:to_i)
# TODO: in ra tổng, tích và giá trị lớn nhất (dùng reduce + khối lệnh tường minh)
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 xử lý
1Tìm hiểu sâu về chuỗi
Tổng quan về phương thức chuỗiNội suy chuỗiDuyệt qua chuỗiTách và nối chuỗiÔn tập: Đan chuỗi4Khối lệnh, Proc và lambda
Khối lệnh là gì?do..end và dấu ngoặc nhọnTừ khóa yieldTham số của khối lệnhProc và lambdaÔn tập: bộ lặp tùy chỉnh7Hash, phần 2
Hash.new với giá trị mặc địnhLặp qua HashHash lồng nhauGộp và chuyển đổiÔn tập: Bộ đếm tần suất10Dự án: Hồ sơ học sinh
Tổng quan dự ánThêm học sinh2Phạm vi
Phạm vi là gì?Các phương thức của phạm viPhạm vi trong case / whenÔn tập: luyện tập với phạm vi5Sức mạnh của Enumerable
select và rejectNối chuỗi mapreduce / injectcount, all?, any?, none?group_by và partitionsort_by, min_by, max_byÔn tập: quy trình dữ liệuTự luyện tập: Trình biên dịch Ruby online