ruby小白课程实战--宠物论坛

2.7 块(Block)和迭代器

2018-12-15  本文已影响15人  808cb3be8e58

在讲数组和哈希之前,我们需要先补充一下块和迭代器的知识,数组和哈希的很多方法涉及到他们

1、块(Block)

块是ruby 的一个独特特性,是一种可以和方法调用相关联的代码块。
是在花括号{}或者do…end之间的一组代码,一般我们在单行中block用花括号{},在多行中用do…end

(1)块的格式
对象.方法名(参数列表)|块变量| 
块代码 
end
对象.方法名(参数列表){|块变量| 块代码 }
(2)块的用法

块(block)与方法关联之后,在关联的方法中用yield语句,调用相关联的block

#定义一个名为block_test的方法
irb(main):001:0> def block_test
#yield代表块里面的内容
irb(main):002:1> yield
irb(main):003:1> yield
irb(main):004:1> yield
irb(main):005:1> end
=> :block_test
#block_test方法后面跟着块{ puts "Hi" },将块关联到了方法上,方法中每个yield语句都会调用一次块
irb(main):006:0> block_test { puts "Hi" }
Hi
Hi
Hi

在实际的项目中,块通常与迭代器结合使用,这样会使代码很简练,下面我们来介绍一下迭代器以及与块的结合使用。

2、迭代器(Enumerator)

迭代器具有遍历容器型数据结构(数组、哈希等)的能力,每一种容器型数据结构(数组、哈希等)都有自己的迭代器。通过块可以很简单的操作迭代器

(1)each,连续访问集合的所有元素,通常在遍历数据时使用
#数组后面跟着each,就是一个迭代器对象,下面返回了数组的each迭代器对象
irb(main):007:0> [1,2,3,4,5].each
=> #<Enumerator: [1, 2, 3, 4, 5]:each>
#在块中(即大括号{}中的代码),两条竖线|i|之间的i代表遍历数组返回的每个数组元素
#puts i将数据每个元素按照顺序打印出来
irb(main):008:0> [1,2,3,4,5].each {|i| puts i }
1
2
3
4
5
(2)map、collect,从集合中获得各个元素传递给块(block),块中代码返回的结果生成新的集合。如果需要将集合中的每个元素做操作返回到一个新数组中,通常使用map。比如将集合中的元素统一换成大写、统一将字符串转换成数组。

map和collect相同的用法。

#将数组的元素统一换成大写
irb(main):023:0> ["a","b","c"].map{|i| i.upcase}
=> ["A", "B", "C"]
#统一将数组中的元素由字符串转换成数组。
irb(main):002:0> ["101","102","103"].map{|x| x.to_i}
=> [101, 102, 103]
#这种写法等同于上面的写法,项目中我们一般都是这样写。需要注意的是,这里用的是小括号()而不是大括号{}
irb(main):003:0> ["101","102","103"].map(&:to_i)
=> [101, 102, 103]
(3)select,从集合中获得各个元素传递给块(block),返回数组中所有满足block条件的值,生成新的集合。
irb(main):014:0> [1,2,3,4,5].select{|i| i>3}
=> [4, 5]
(4)reject,从集合中获得各个元素传递给块(block),返回数组中所有不满足block条件的值,生成新的集合。
irb(main):099:0> [1,2,3,4,5].reject{|i| i>3}
=> [1, 2, 3]
(5)inject,遍历整个集合中的各个元素,将各个元素,按照一定的方式累积,最后返回一个新的元素。
#inject后面跟的块有两个参数,第一次遍历时,第一个参数是数组第一个值,第二个参数是数组第二个值
#之后遍历,块中代码计算的值传给sum,而per是数组中元素的遍历
irb(main):016:0> [1,2,3,4,5].inject {|sum,per| sum+per}
=> 15
#让我们更加直观的看一下
irb(main):015:0> [1,2,3,4,5].inject {|sum,per| puts "sum:#{sum},per:#{per}";sum+per}
sum:1,per:2
sum:3,per:3
sum:6,per:4
sum:10,per:5
=> 15
#当inject后面指定了参数,第一个sum就是指定的这个参数  ,而per也是数组的第一个值
irb(main):017:0> [1,2,3,4,5].inject(7) {|sum,per| puts "sum:#{sum},per:#{per}";sum+per}
sum:7,per:1
sum:8,per:2
sum:10,per:3
sum:13,per:4
sum:17,per:5
=> 22
上一篇下一篇

猜你喜欢

热点阅读