Enumerable模块

可枚举模块。 Enumerable mixin 是含有几组遍历与查寻方法的集合类,而且它还有排序的能力。

如果你希望自己的类也具有集合类这么多优秀的特点,那么这个类必须提供一个 each 方法,在这个方法内,它产生连续的集合成员。即依次返回你自己集合类的元素。然后再在你的类中混合插入 Enumerable 模块,你的类就可支持 mapinclude?find_all? 等方法了。若你集合内的元素再支持 <=> 方法,即集合内的元素混合插入了 Comparable 模块,那么这个集合也可以得到 minmaxsort 等方法。

 

实例方法:

(1) enum.all? [{|obj| block } ] => true or false enum.any? [{|obj| block } ] => true or false 将集合内的每个元素传递给块。即依次为集合内的各个元素来执行块的内容。当所有元素为真时, all 返回 true 。当所有元素为假时, any 返回 false 。如果忽略了 block 块,则 Ruby 会偷偷地添加一个 {|obj|obj} 块。

例如:

%w{ ant bear cat}.all? {|word| word.length >= 3} #=> true

%w{ ant bear cat}.all? {|word| word.length >= 4} #=> false

[ nil, true, 99 ].all? #=> false

 

%w{ ant bear cat}.any? {|word| word.length >= 3} #=> true

%w{ ant bear cat}.any? {|word| word.length >= 4} #=> true

[ nil, true, 99 ].any? #=> true

 

(2) enum.collect {| obj | block } => array enum.map {| obj | block } => array 依次为 enum 内的每个元素执行块 block 的内容,并将结果存入一个新数组中,最后返回该数组。

例如:

(1..4).collect {|i| i*i } #=> [1, 4, 9, 16]

(1..4).collect { "cat" } #=> ["cat", "cat", "cat", "cat"]

省略块时,会执行 obj.collect {|item| item} 这等同于 Enumerable#to_a

注: collect 有收集,采集的含义。

(3) enum.each_with_index {|obj, i| block } → enum 对于 enum 内的每个条目,使用元素及其索引进行循环操作的迭代器,即使用两个参数调用块。并返回 self

例如:

hash = Hash.new

%w(cat dog wombat).each_with_index {|item, index|

hash[item] = index }

hash #=> {"cat"=>0, "wombat"=>2, "dog"=>1}

 

(4) enum.detect(ifnone = nil) {| obj | block } => obj or nil enum.find(ifnone = nil) {| obj | block } => obj or nil 传递 enum 内的每个元素给块 block 进行计算,返回计算值首次为真的那个元素。若块的计算始终都不为真的话,则计算 ifnone 部分 ( 如果有的话 ) 并返回它的值,或者返回 nul

例如:

(1..10).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> nil

(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 } #=> 35

注: detectfind 单词都有查明真相的意思,用在这个方法上,是因为它要查出每个元素经过计算后的真相,即是否为真。

 

(5) enum.find_all {| obj | block } => array enum.select {| obj | block } => array 在使用元素进行块计算时,若计算值为真,则把该元素存入数组,最后返回该数组。若块的计算始终都不为真时,则返回空数组。

例如:

(1..10).find_all {|i| i % 3 == 0 } #=> [3, 6, 9]

注: select 有挑选的意思。把计算后为真的元素挑选出来。

 

(6) enum.grep(pattern) => array enum.grep(pattern) {| item | block } => array pattern === item ,则把该元素存入数组,最后返回该数组,若带块调用时,则会依次为所有满足上述条件的元素来执行块的内容,并把计算结果存入到数组,最后返回该数组。若没有符合条件的元素时,返回空数组。

例如:

(1..100).grep 38..44 #=> [38, 39, 40, 41, 42, 43, 44]

 

c = IO.constants

c.grep(/SEEK/) #=> ["SEEK_END", "SEEK_SET", "SEEK_CUR"]

res = c.grep(/SEEK/) {|v| IO.const_get(v) }

res #=> [2, 0, 1]

注: grep 这个单词在 UNIX 中是一个工具程序。可用做文件内的字符串查找。

 

(7) enum.inject(initial) {| memo, obj | block } => obj enum.inject {| memo, obj | block } => obj 在每一步骤中, memo 要被设置为由块计算后返回的值。首先,用 initial 初始化 memo 的值,并将 memoobj 参数传递给块进行计算。然后将上步块计算后的值赋值给 memo 后,再继续计算块,以此类推。

其中, enum 集合中的每个元素依次赋值给 obj 。而 memo 的初始是 initial ,尔后则是由 block 块计算出来的值。这样一直循环到 enum 的最后元素,并将最后的块的计算结果返回。

若省略了初始值 initial 的话,开始时会把第 1 和第 2 个元素传递给块。 此时,若只有 1 个元素时,将直接返回首元素,而不会执行块。 若没有元素,则返回 nil

例如:求和的计算

p [1,2,3,4,5].inject(0) {|result, item| result + item } #=> 15

这等同于

result = 0

[1,2,3,4,5].each {|v| result += v }

p result #=> 15

再如:

# 查找最长的单词

longest = %w{ cat sheep bear }.inject do |memo,word|

memo.length > word.length ? memo : word

end

longest #=> "sheep"

# 查找最长单词的长度。

longest = %w{ cat sheep bear }.inject(0) do |memo,word|

memo >= word.length ? memo : word.length

end

longest #=> 5

注:这个方法之所以用 inject 这个单词,是因为这个方法有个注射动作,即将 initial 及后来的块计算结果注入到 memo 中。

 

(8) enum.include?(obj) => true or false enum.member?(obj) => true or false obj== 某元素时,返回真。

 

(9) enum.max => obj enum.max {|a,b| block } => obj

enum.min => obj enum.min {| a,b | block } => obj 返回最大与最小的元素。不带块的第一种形式是假设 enum 的所有元素都实现了 Comparable 模块。第二种形式块使用 <=> 来判断 enum 内各个元素的大小。通常要求该块返回下列各整数值:当 a>b 时返回正整数, a==b 时返回 0 ,而 a<b 时返回负整数。若该块返回了一个非整数值时,会引发 TypeError 异常。

例如:

a = %w(albatross dog horse)

a.min #=> "albatross"

a.min {|a,b| a.length <=> b.length } #=> "dog"

 

a.max #=> "horse"

a.max {|a,b| a.length <=> b.length } #=> "albatross"

 

(10) enum.partition {| obj | block } => [ true_array, false_array ] 若对某元素执行块的结果为真,则把该元素归入第一个数组;若为假则将其归入第二个数组 , 最后生成并返回一个包含这两个数组的新数组。

例如:

(1..6).partition {|i| (i&1).zero?} #=> [[2, 4, 6], [1, 3, 5]]

注:硬盘的分区就使用这个单词。只是没有想到我们要操作的一些对象,也可以被“分区”的。

 

(11) enum.reject {| obj | block } => array enum 内的各元素依次传入块中进行计算,若计算值为假则将该元素存入数组,最后返回该数组。

例如:

(1..10).reject {|i| i % 3 == 0 } #=> [1, 2, 4, 5, 7, 8, 10]

注: reject 有不合格者,不合格品的意思。

 

(12) enum.sort => array enum.sort {| a, b | block } => array 对所有元素进行升序排列后返回这个新的数组。若不带块时,将以 <=> 方法的比较结果为基础进行排序。如果想借用 <=> 之外的方法进行排序时,可以指定一个块。此时将以块的计算结果为基础进行排序。通常要求该块返回下列各值:当 a>b 时返回正整数, a==b 时返回 0 ,而 a<b 时返回负整数。若该块返回了一个非整数值时,会引发 TypeError 异常。

Enumerable#sort 所进行的是不稳定的排序 (unstable sort)

注:排序后,若相等的元素的位置并未改变的话,这种排序就是 " 稳定的排序 (stable sort)"

例如:

%w(rhea kea flea).sort #=> ["flea", "kea", "rhea"]

(1..10).sort {|a,b| b <=> a} #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值