Ruby's Enumerable Module and yield method

简介:
+关注继续查看
Hash, Array, Range, Set 类的对象为什么可以使用include?, min, max等方法, 原因是这些CLASS包含了Enumerable模块.
这个模块的详细介绍可以在Ruby Core API Reference中查询.
下面对某些方法举例说明 : 
测试版本1.9.3-p0
一、内建类型的Enumerable方法调用
1. min
a = Array.new(['z','abc','bc','d1','efg'])
p(a.min)   #=>"abc" , 默认情况下min 判断的是ascii码
p(a.min{
 |x|
 x.length
 })  #=>"z" , 这里判断的是字符长度.


2. max
a = {'z'=>'digoal',
 'abc'=>'francs',
 'bc'=>'dage',
 'd1'=>'hank',
 'efg'=>'new'}
p(a) #=>{"z"=>"digoal", "abc"=>"francs", "bc"=>"dage", "d1"=>"hank", "efg"=>"new"}
p(a.max) #=>["z", "digoal"]
p(a.max{
 |x|
 x.length
 }) #=>["efg", "new"] , 这里判断的是hash key的字符长度.


3. sort
a = {'z'=>'digoal',
 'abc'=>'francs',
 'bc'=>'dage',
 'd1'=>'hank',
 'efg'=>'new'}
p(a) #=> {"z"=>"digoal", "abc"=>"francs", "bc"=>"dage", "d1"=>"hank", "efg"=>"new"}
p(a.sort) #=> [["abc", "francs"], ["bc", "dage"], ["d1", "hank"], ["efg", "new"], ["z", "digoal"]] , 默认按ASCII排序
p(a.sort{
 |x,y|
 x[0].length <=> y[0].length
 }) #=> [["z", "digoal"], ["d1", "hank"], ["bc", "dage"], ["abc", "francs"], ["efg", "new"]]  , 这里按照Hash key的长度排序
p(a.sort{
 |x,y|
 x[1].length <=> y[1].length
 }) #=> [["efg", "new"], ["d1", "hank"], ["bc", "dage"], ["abc", "francs"], ["z", "digoal"]] , 这里按照Hash value的长度排序


4. collect
a = [1,2,3,4,5,6]
b = a.collect {
 |x|
 x * x
}
p(a) #=> [1, 2, 3, 4, 5, 6]
p(b) #=> [1, 4, 9, 16, 25, 36] , collect方法重新构造一组数据.


5. include?
a = [1,2,3,4,5,6]
p(a.include?(1)) #=> true , 判断是否包含1
p(a.include?(7)) #=> false , 判断是否包含7


二、自定义CLASS中包含Enumerable模块举例 : 
class MyClass
 include Enumerable # 这个指包含Enumerable模块
 def initialize( someItems )
  @items = someItems
 end

 def each # 要在自定义类中使用Enumerable模块中的方法, 必须写一个each 方法, 告诉其他要调用的Enumerable方法每次传什么值进去.
  @items.each{
                       |i|
   yield(i)  # yield方法里面的参数, 就是表示其他要调用的Enumerable方法每次传什么值进去.这里每次传的就是i
  }
 end
end

a = MyClass.new(['c','bda1a','baz','ce','zwfg'])
p(a) #=> #<MyClass:0x1ef0db0 @items=["c", "bda1a", "baz", "ce", "zwfg"]>
p(a.sort) #=> ["baz", "bda1a", "c", "ce", "zwfg"]

class MyClass
 include Enumerable
 def initialize( someItems )
  @items = someItems
 end

 def each
  @items.each{
   |i|
   yield(i.to_s.length) #这里每次传的是i.to_s.length
  }
 end
end

a = MyClass.new(['c','bda1a','baz','ce','zwfg'])
p(a) # => #<MyClass:0x1e90c90 @items=["c", "bda1a", "baz", "ce", "zwfg"]>
p(a.sort) # => [1, 2, 3, 4, 5]

# 自定义类型中如果没有定义each方法, 但是调用了Enumerable中的方法会报错, 例如 : 
`sort': undefined method `each' for #<MyClass:0x1ebfb08 @items=["c", "bda1a", "baz", "ce", "zwfg"]> (NoMethodError)

【参考】
Ruby Core API Reference : Enumerable
The Book of Ruby : Page 100 - 105
目录
相关文章
|
2月前
|
PyTorch 算法框架/工具 Python
AttributeError: module ‘distutils‘ has no attribute ‘version‘解决跑pytorch代码报错
AttributeError: module ‘distutils‘ has no attribute ‘version‘解决跑pytorch代码报错
|
6月前
AttributeError: cannot assign module before Module.__init__() call 怎么解决?
这个错误通常是由于在__init__方法之外对模块中的某些成员进行了初始化或赋值操作,导致模块还没有被完全初始化就已经被调用了。为了解决这个问题,你需要将所有的初始化或赋值操作移到__init__方法内部。 例如,如果你有一个自定义模块MyModule,并且想要在其中定义一个类变量my_var,则应该将其放在__init__方法中:
236 0
|
C# Python
python与C#的互相调用(No module named XX)
python与C#的互相调用(No module named XX)
python与C#的互相调用(No module named XX)
|
Python
Python 语法问题-module ‘pip._internal‘ has no attribute ‘pep425tags‘. 原因及解决办法,32位、64位查看pip支持万能方法
Python 语法问题-module ‘pip._internal‘ has no attribute ‘pep425tags‘. 原因及解决办法,32位、64位查看pip支持万能方法
300 0
Python 语法问题-module ‘pip._internal‘ has no attribute ‘pep425tags‘. 原因及解决办法,32位、64位查看pip支持万能方法
|
Python
Python3 多线程问题:ModuleNotFoundError: No module named 'thread',原因及解决办法。
Python3 多线程问题:ModuleNotFoundError: No module named 'thread',原因及解决办法。
371 0
|
Python
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法
264 0
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法
相关产品
云迁移中心
推荐文章
更多