Menu
Coddy logo textTech

Das Enumerable-Modul

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 30 von 57.

Enumerable ist das Modul hinter den Sammlungsmethoden von Arrays und Hashes. Eine Klasse, die each definiert, ihre Elemente einzeln ausgibt und Enumerable einbindet, erhält map, select, count, sort_by, min_by, sum, include? und Dutzende weitere Methoden:

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

Ausgabe:

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

yield übergibt einen Wert an den Block, den der Aufrufer an each übergeben hat. Die Klasse legt fest, was ein Element ist, zum Beispiel eine Textzeile, ein Wertepaar oder eines ihrer eigenen Objekte:

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 }

Ausgabe:

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

Die Elemente müssen nicht gespeichert werden. each kann sie während der Verarbeitung berechnen, und Methoden wie first beenden die Schleife vorzeitig:

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

Ausgabe:

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

Wenn die Elemente <=> definieren, funktionieren die Sortiermethoden von Enumerable wie sort, min und max ohne einen Block. Andernfalls benötigen sie einen, wie bei sort_by und min_by:

class Team
  include Enumerable

  def each(&block)
    @players.each(&block)     # den Block direkt weitergeben
  end
end

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

Aufgabe

Einfach

Vervollständige die Klasse Playlist. Sie enthält Song-Objekte (mit title und seconds), die mit add hinzugefügt werden, bindet Enumerable ein und definiert each, das jedes Lied in der Reihenfolge seiner Hinzufügung liefert.

Der bereitgestellte Code fügt pro Eingabezeile (title,seconds) ein Lied hinzu und verwendet anschließend ausschließlich Enumerable-Methoden auf der Playlist: Er gibt die Anzahl der Lieder, die durch Kommas verbundenen Titel, die Gesamtlänge im Format m:ss, den Titel des längsten Liedes und die Titel der Lieder mit einer Länge von über 3 Minuten in alphabetischer Reihenfolge aus (oder none).

Dein Code gehört in song.rb und playlist.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.

ERFORDERLICHES AUSGABEFORMAT: [Dein übersetzter Inhalt hier]

Probier es selbst

require_relative 'song'
require_relative 'playlist'

# Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler