2.7 块(Block)和迭代器

作者: 808cb3be8e58 | 来源:发表于2018-12-15 23:39 被阅读15次

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

    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
    

    相关文章

      网友评论

        本文标题:2.7 块(Block)和迭代器

        本文链接:https://www.haomeiwen.com/subject/ruakhqtx.html