Module Enumerable
Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 30 trên 57.
Enumerable là module đứng sau các phương thức xử lý tập hợp của mảng và hash. Một lớp định nghĩa each, lần lượt trả về từng phần tử và bao gồm Enumerable sẽ có các phương thức map, select, count, sort_by, min_by, sum, include? và hàng chục phương thức khác:
class Playlist
include Enumerable
def initialize(*songs)
@songs = songs
end
def each
@songs.each { |song| yield song }
end
end
list = Playlist.new("Intro", "Dune", "Outro")
puts list.map(&:upcase).join(", ")
puts list.select { |s| s.size > 4 }.inspect
puts list.count
puts list.include?("Dune")Đầu ra:
INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
trueyield truyền một giá trị cho khối lệnh mà bên gọi đã đưa vào each. Lớp quyết định một phần tử là gì, chẳng hạn như một dòng văn bản, một cặp giá trị hoặc một trong những đối tượng của chính nó:
class Inventory
include Enumerable
def initialize
@stock = { "apple" => 3, "pear" => 0, "plum" => 7 }
end
def each
@stock.each { |name, qty| yield name, qty }
end
end
inv = Inventory.new
p inv.select { |_, qty| qty.positive? }.map(&:first)
p inv.max_by { |_, qty| qty }Đầu ra:
["apple", "plum"]
["plum", 7]Các phần tử không cần phải được lưu trữ. each có thể tính chúng trong lúc duyệt, còn các phương thức như first sẽ dừng vòng lặp sớm:
class Squares
include Enumerable
def initialize(limit)
@limit = limit
end
def each
n = 1
while n * n <= @limit
yield n * n
n += 1
end
end
end
p Squares.new(50).to_a
p Squares.new(1000).first(3)
puts Squares.new(100).sumĐầu ra:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385Khi các phần tử định nghĩa <=>, các phương thức sắp xếp của Enumerable, như sort, min và max, hoạt động mà không cần khối lệnh. Nếu không, chúng cần một khối lệnh, như trong sort_by và min_by:
class Team
include Enumerable
def each(&block)
@players.each(&block) # chuyển thẳng khối lệnh (block) sang
end
end
team.sort_by(&:age)
team.min_by(&:score)Thử thách
DễHoàn thiện lớp Playlist. Lớp này chứa các đối tượng Song (có title và seconds) được thêm bằng add, bao gồm Enumerable và định nghĩa each, phương thức này lần lượt trả về từng bài hát theo thứ tự được thêm vào.
Code được cung cấp thêm một bài hát cho mỗi dòng đầu vào (title,seconds), sau đó chỉ dùng các phương thức của Enumerable trên danh sách phát: in ra số bài hát, các tiêu đề được nối bằng dấu phẩy, tổng thời lượng theo định dạng m:ss, tiêu đề bài hát dài nhất và tiêu đề của những bài hát dài hơn 3 phút, được sắp xếp theo thứ tự bảng chữ cái (hoặc none).
Code của bạn nằm trong song.rb và playlist.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.
Tự làm thử
require_relative 'song'
require_relative 'playlist'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
input << line.chomp
end
list = Playlist.new
input.each do |line|
title, seconds = line.split(",")
list.add(Song.new(title, seconds.to_i))
end
total = list.sum(&:seconds)
long = list.select { |s| s.seconds > 180 }.map(&:title).sort
puts "songs: #{list.count}"
puts "titles: #{list.map(&:title).join(", ")}"
puts format("total: %d:%02d", total / 60, total % 60)
puts "longest: #{list.max_by(&:seconds).title}"
puts "over 3 min: #{long.empty? ? "none" : long.join(", ")}"
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 Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpBiến instancePhương thức và selfto_s và inspectÔn tập: thẻ thư viện4Tính đóng gói
Phương thức riêng tưPhương thức được bảo vệPhương thức thiết lập riêng tưBảo vệ trạng tháiÔn tập: máy bán hàng tự động7Tính đa hình và duck typing
Tính đa hìnhDuck typingPhương thức trừu tượngcase và lớpÔn tập: phương thức thanh toán2Phương thức truy cập và self
Phương thức đọc và ghiPhương thức gán tùy chỉnhself trong phương thứcĐịnh danh và tính bằng nhauÔn tập: Danh sách liên hệ3Phương thức và biến của lớp
Phương thức lớpBiến thực thể của lớpHằng sốPhương thức tạo đối tượngÔn tập: mã giảm giá6Module và mixin
Module và includeMở rộng đối tượngModule ComparableModule EnumerableÔn tập: giải đấu thể thaoTự luyện tập: Trình biên dịch Ruby online