Menu
CoddyTech

module Enumerable

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 30 dari 57.

Enumerable adalah module di balik method koleksi pada array dan hash. Class yang mendefinisikan each, lalu menghasilkan elemennya satu per satu, dan menyertakan Enumerable akan mendapatkan map, select, count, sort_by, min_by, sum, include?, dan puluhan lainnya:

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

Output:

INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
true

yield meneruskan nilai ke blok yang diberikan pemanggil kepada each. Class menentukan apa yang dimaksud dengan satu elemen, misalnya sebaris teks, sepasang nilai, atau salah satu object miliknya:

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 }

Output:

["apple", "plum"]
["plum", 7]

Elemen-elemennya tidak harus disimpan. each dapat menghitungnya sambil berjalan, dan method seperti first menghentikan perulangan lebih awal:

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

Output:

[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385

Jika elemen mendefinisikan <=>, method pengurutan dari Enumerable, seperti sort, min, dan max, dapat digunakan tanpa blok. Jika tidak, method tersebut memerlukan blok, seperti sort_by dan min_by:

class Team
  include Enumerable

  def each(&block)
    @players.each(&block)     # teruskan block secara langsung
  end
end

team.sort_by(&:age)
team.min_by(&:score)
challenge icon

Tantangan

Mudah

Lengkapi class Playlist. Class ini menyimpan object Song (dengan title dan seconds) yang ditambahkan dengan add, menyertakan Enumerable, dan mendefinisikan each, yang menghasilkan setiap lagu sesuai urutan penambahannya.

Kode yang disediakan menambahkan satu lagu untuk setiap baris input (title,seconds), lalu hanya menggunakan method Enumerable pada playlist: kode ini mencetak jumlah lagu, judul yang digabungkan dengan koma, durasi total dalam m:ss, judul lagu terpanjang, dan judul lagu yang durasinya lebih dari 3 menit, diurutkan berdasarkan abjad (atau none).

Tulis kodemu di song.rb dan playlist.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

require_relative 'song'
require_relative 'playlist'

# Kode input/output yang disediakan: biarkan apa adanya
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(", ")}"
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Ruby online