Ruby 的迭代器
ruby中针对集合(数组、哈希)的迭代器有 each map collect inject,下面将逐一介绍
1 each用法
each方法是最简单也最常用的,它会连续访问集合的所有元素然后传值给bloc执行,比如:
1 2 3 |
|
运行结果:
1
2
3
4
5
2 reverse_each 用法:
对比each,从字面上理解reverse_each就是逆序迭代,例如
1 2 |
|
运行结果
3
2
1
a.reverse_each 和 a.reverse.each 有什么区别呢? 功能是一样的,但是效率不同, reverse_each的效率更高
1 2 3 4 |
|
3 map用法
map也很常用,它从集合中获得各个元素传递给block,block返回的结果生成新的集合,比如:
[1,2,3,4,5].map{ |a| a + 1 } -> [2, 3, 4, 5, 6]
再比如:
1 2 |
|
这个例子可以简写成: users.map(&:name)
,其运行结果也是一样的
4 collect用法
同map一样。
5 inject用法
inject是最有魅力的一个方法,字面意思是‘注入’,可以理解为是一个具有Combines(联合、合并)功能的迭代器,比如:
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
inject带有一个参数和block,参数是初始值,另外给block中传递了两个值,第一个result是Combines操作的值,第二个参数element是迭代传入集合的每个元素。reslut在inject第一次执行block时把inject带的参数付值给它,该例中inject一共执行4次block,每次执行block完后,最后语句的结果再付值给result,如此循环,直到遍历数组中所有元素。我们深入这个例子看每一步执行的结果。
因为数组有4个元素,所以要执行4次block操作:
第一次操作:result=0,既等于inject带的参数;element=1,既第一个元素;
执行block后result + element =1,再把这个结果付值给result,所以在执行完第一次block后,result = 1。
第二次操作:result=1,既上次运行block后的最后一条语句的结果;element=2,既第二个元素;执行block后付值result=3。
如此类推,直到最后一次执行完block,生产的值为10。就是inject的返回值了。
inject可以不带参数,此时result的初始值为数组元素的第一个值,element从第二个元素开始传值。所以上例可改写成:
[2, 3, 4].inject{ |result, element| result*element } # => 24
注意:这时block执行的次数是3次!而不是4次。
再例如:
1 2 3 4 5 |
|
注意:这个例子中第三行的result不能省略,否则会报错。
继续举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
最后一个例子:
1 2 3 4 5 |
|
其它: all? 和 any?
all?[{|obj| block } ] → true or false
all?
方法遍历集合中的每一个元素并传值给block,
如果block返回结果为包含false或nil,all?方法返回false;
如果block返回结果都为true,all?方法返回true;
如果没有给定block,只要集合中有一个值为false或nil,那么最终结果就是false
例如:
1 2 3 |
|
any?[{|obj| block } ] → true or false
any?方法遍历集合中的每一个元素并传值给block,
如果block返回结果有一个不为false或nil,any?方法返回true;
如果没有给定block,只要集合中有一个值不为false或nil,那么最终结果就是tru
1 2 3 |
|