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