包含 Enumerable
免费获得 map/select
包含 Enumerable 是 CoddyKit 上的免费 Ruby Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Ruby Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Ruby Academy 课程共包含 4 节课。
免费获得 map 和 select
类拥有 each 后,混入 Enumerable 就会立即获得 map、select、reduce、sort、min、max 等许多方法,而这些方法都建立在您的 each 之上。
class Bag
include Enumerable
def initialize(*x); @x = x; end
def each; @x.each { |i| yield i }; end
end
p Bag.new(1, 2, 3).map { |n| n * 10 }契约
规则很简单:包含 Enumerable 并定义 each。Enumerable 会在内部调用您的 each,以实现其他所有功能。
class Squares
include Enumerable
def initialize(n); @n = n; end
def each
(1..@n).each { |i| yield i * i }
end
end
p Squares.new(5).to_a使用 select 进行筛选
select 会保留代码块返回真值的元素。reject 则执行相反的操作。
class Nums
include Enumerable
def initialize(*x); @x = x; end
def each; @x.each { |i| yield i }; end
end
n = Nums.new(1, 2, 3, 4, 5, 6)
p n.select(&:even?)
p n.reject(&:even?)使用 reduce 进行聚合
reduce 会将集合折叠为单个值。
class Cart
include Enumerable
def initialize(*p); @p = p; end
def each; @p.each { |i| yield i }; end
end
puts Cart.new(5, 10, 15).reduce(:+)min、max 和 sort
只要您的元素具有可比较性,基于比较的方法就能正常工作。
class Scores
include Enumerable
def initialize(*n); @n = n; end
def each; @n.each { |i| yield i }; end
end
s = Scores.new(7, 2, 9, 4)
puts s.min
puts s.max
p s.sortfind 和 include?
find 会返回第一个匹配的元素;include? 会检查成员关系。
class Words
include Enumerable
def initialize(*w); @w = w; end
def each; @w.each { |x| yield x }; end
end
w = Words.new("cat", "dog", "bird")
puts w.find { |x| x.length == 4 }
puts w.include?("dog")group_by 和 partition
Enumerable 提供了强大的分组辅助功能。
class Nums
include Enumerable
def initialize(*x); @x = x; end
def each; @x.each { |i| yield i }; end
end
n = Nums.new(1, 2, 3, 4, 5)
p n.group_by(&:even?)
p n.partition(&:odd?)排序需要可比较的元素
如果元素是自定义对象,请通过 Comparable 为它们提供 <=>,这样 sort、min 和 max 才知道如何排列它们。
Item = Struct.new(:price) do
include Comparable
def <=>(o); price <=> o.price; end
end
class Shelf
include Enumerable
def initialize(*i); @i = i; end
def each; @i.each { |x| yield x }; end
end
shelf = Shelf.new(Item.new(30), Item.new(10), Item.new(20))
p shelf.min.price带索引的迭代
Enumerable 还提供 each_with_index 和 each_with_object,用于进行更丰富的迭代。
class Letters
include Enumerable
def initialize(*l); @l = l; end
def each; @l.each { |x| yield x }; end
end
Letters.new("a", "b", "c").each_with_index do |letter, i|
puts "#{i}: #{letter}"
end串联方法
由于这些方法会返回数组或枚举器,您可以将它们串联成清晰易懂的流水线。
class Nums
include Enumerable
def initialize(*x); @x = x; end
def each; @x.each { |i| yield i }; end
end
result = Nums.new(1, 2, 3, 4, 5, 6).select(&:even?).map { |n| n * n }
p result整合运用
包含 Enumerable 会带来巨大收益:
- 只需定义一次
each。 - 即可获得 map、select、reduce、sort、find、group_by 以及数十种其他功能。
- 为元素添加 Comparable,以支持排序方法。
class Range5
include Enumerable
def each; (1..5).each { |n| yield n }; end
end
puts Range5.new.sum快速检查
测试您对包含 Enumerable 的理解。
回顾
您学习了如何包含 Enumerable:
- 定义
each,包含该模块,即可获得完整工具集。 - map、select、reduce、find 和 group_by 都基于您的
each运行。 - 元素排序需要
<=>。 - 方法可以串联成流水线。
class Tens
include Enumerable
def each; [10, 20, 30].each { |n| yield n }; end
end
p Tens.new.map { |n| n + 1 }常见问题解答
「包含 Enumerable」课时是免费的吗?
是的 — 「包含 Enumerable」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Ruby Academy 课程的其余内容,请升级到 CoddyKit PRO。 Ruby Academy 课程共包含 4 节课。
「包含 Enumerable」这节课中我会学到什么?
免费获得 map/select 你通过在浏览器中直接运行的动手代码来练习 Ruby Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Ruby Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Ruby Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「包含 Enumerable」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Ruby Academy 课中编写并运行代码吗?
能。每节 Ruby Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 编写自定义 each
- 包含 Enumerable
- 惰性枚举器
- 枚举器对象