وحدة Enumerable
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 30 من 57.
Enumerable هو الوحدة التي تقف وراء أساليب المجموعات الخاصة بالمصفوفات والتجزئات. الفئة التي تعرّف each، بحيث تُنتج عناصرها واحدًا تلو الآخر، وتضمّن Enumerable تحصل على map وselect وcount وsort_by وmin_by وsum وinclude? والعشرات غيرها:
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")الناتج:
INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
trueيمرّر yield قيمةً إلى الكتلة التي يمرّرها المستدعي إلى each. يحدّد الصنف ماهية العنصر الواحد، مثل سطر من النص، أو زوج من القيم، أو أحد كائناته الخاصة:
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 }الناتج:
["apple", "plum"]
["plum", 7]لا يلزم تخزين العناصر. يمكن لـ each حسابها أثناء تقدّمه، وتوقف أساليب مثل first الحلقة مبكرًا:
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الناتج:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385عندما تعرّف العناصر <=>، تعمل طرق الفرز في Enumerable، مثل sort وmin وmax، من دون كتلة. وإلا فإنها تتطلب كتلة، كما في sort_by وmin_by:
class Team
include Enumerable
def each(&block)
@players.each(&block) # مرّر الـ block مباشرةً
end
end
team.sort_by(&:age)
team.min_by(&:score)التحدي
سهلأكمل الصنف Playlist. فهو يحتوي على كائنات Song (مع title وseconds) تتم إضافتها باستخدام add، ويتضمن Enumerable ويعرّف each، الذي يُنتج كل أغنية بالترتيب الذي أُضيفت به.
يضيف الكود المُ supplied أغنية واحدة لكل سطر إدخال (title,seconds)، ثم يستخدم فقط أساليب Enumerable على قائمة التشغيل: يطبع عدد الأغاني، والعناوين مفصولة بفواصل، والمدة الإجمالية بتنسيق m:ss، وعنوان أطول أغنية، وعناوين الأغاني التي تتجاوز 3 دقائق، مرتبة أبجديًا (أو none).
ضع الكود الخاص بك في song.rb وplaylist.rb. يحتوي main.rb على كود الإدخال/الإخراج المُ supplied ولا يمكن تعديله.
جرّب بنفسك
require_relative 'song'
require_relative 'playlist'
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
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(", ")}"
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت