携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
一、枚举
可枚举模块不同于前面的 String、Integer 和 Symbol 类,枚举是一个抽象出来的概念。枚举可以视为是可搜索、可遍历以及可以排序的集合,可枚举类型不是常见的基本类型,它为容器类的类型提供了可枚举的能力既大量地包含遍历、搜索和排序等集合操作的方法和功能。
枚举模块中也可以混入自定义的类中,通过 mixin 和 可枚举模块 Enumerable 模块的设计,自己创建的类瞬间可以获得可枚举的能力,直接获得大量的集合操作方法。
可枚举模块中的方法可以分为两类,一类是遍历和搜索方法,适合无须集合进行操作,另一类是比较和排序方法,适合集合类元素之间有比较方法时,可以进行的操作。
遍历和搜索方法
可枚举模块中的便来和搜索方法包括以下几种
enum.all?{|obj| block}
判断集合中是否所有元素都满足指定条件,条件时通过 block 代码块来设置的,运行时依次传入集合中的元素给 block 代码块,如果代码块一直没有返回 false 或者 nil,则方法返回 true,否则返回 false
arr = [1, 2, 3, 4, 5]
res1 = arr.all?{|i| i >= 1}
res2 = arr.all?{|i| i >= 2}
puts res1 # true
puts res2 # false
enum.any?{|obj| block}
判断集合中任意一个元素是否满足某个条件,运行方式与 enum.all?{|obj| block} 类似,只要有一个元素在 block 代码中返回 true,则方法返回 true,否则返回 false
arr = [1, 2, 3, 4, 5]
res1 = arr.any?{|i| i / 2 == 1}
res2 = arr.any?{|i| i >= 10}
puts res1 # true
puts res2 # false
enum.collect{|obj| block}
集合中每一个元素依次传递给 block 代码块,结果以数组的形式返回
arr = [1, 2, 3, 4, 5]
res1 = arr.collect{|i| i += 1}
res2 = arr.map{|i| i += 10}
puts res1
puts res2
执行上述代码,输出结果如下:
2
3
4
5
6
11
12
13
14
15
enum.map 方法的作用等同于 enum.collect 方法
enum.each_with_index{|obj, i| block }
类似于 enum.each 方法,不过 enum.each_with_index 调用 block 代码块是会传入两个参数,第一个参数是集合中的每一个元素,第二个参数是该元素的索引,这个方法返回的结果是一个数组。
arr = [1, 2, 3, 4, 5]
res1 = arr.each_with_index{|item, i| puts "第 #{i} 位置上的元素为 #{item}"}
puts res1.class
puts res1
执行上述代码,输出结果如下:
第 0 位置上的元素为 1
第 1 位置上的元素为 2
第 2 位置上的元素为 3
第 3 位置上的元素为 4
第 4 位置上的元素为 5
Array
1
2
3
4
5
enum.find(ifnone=nil){|obj| block }
寻找符合条件的某一个元素,运行时一次传递每个元素给 block 代码块,直到返回第一个使得 block 结果为 true 的元素,如果没有任何符合条件的元素,则返回空
arr = [1, 2, 3, 4, 5]
res1 = arr.find(ifnone=nil){|i| i / 2 == 0}
res2 = arr.find(ifnone=nil){|i| i > 5}
puts res1
puts res2
执行上述代码,输出结果如下:
1
enum.find_all{|obj| block }
寻找所有符合条件的元素,enum.select 与该方法功能相同
arr = [1, 2, 3, 4, 5]
res1 = arr.find_all{|i| i > 2}
res2 = arr.select{|i| i > 2}
puts res1
puts res2
执行上述代码,输出结果如下:
3
4
5
3
4
5
enum.include?(obj)
判断集合中是否包含 obj
arr = [1, 2, 3, 4, 5]
res1 = arr.include?(2)
puts res1 # true
enum.inject(initial=nil){|memo, obj| block }
遍历集合并累计集合中元素在 block 代码中结果的和,运行的方式是遍历集合中,每一步 memo 参数都会被设置为 block 运行的结果,再传入下一步运算,如果指定了 initial 参数,则 memo 的初始值就是 initial 参数,否则以第一个元素的值为 memo 的初始值,并且第一个元素不再进入迭代。
arr = [1, 2, 3, 4, 5]
res1 = arr.inject(initial = 0){|sum, i| sum + i}
puts res1 # 15
res2 = arr.inject(initial = 1){|product, i| product * i}
puts res2 # 120
enum.partition{|obj| block }
将集合按照条件分割,返回两个数组,第一个数组包含集合中使得 block 为真的元素,另外一个返回使block 为 false 的元素集合
arr = [1, 2, 3, 4, 5]
res1 = arr.partition{|i| i > 2}
puts res1.to_s # [[3, 4, 5], [1, 2]]