zoukankan      html  css  js  c++  java
  • ruby迭代器iterator和枚举器Enumerator

    编写自定义的迭代器

    The defining feature of an iterator method is that it invokes a block of code associated
    with the method invocation. You do this with the yield statement. The following
    method is a trivial iterator that just invokes its block twice:
    def twice
     yield
      yield
    end

    To pass argument values to the block, follow the yield statement with a comma separated
    list of expressions. As with method invocation, the argument values may
    optionally be enclosed in parentheses. The following simple iterator shows a use of
    yield:

    def sequence(n,m,c)
        i=0
        while(i<n)
            yield m*i+c
            i+=1
        end
    end
    sequence(3,5,1) { |y| puts y}

    下面是ruby迭代器的另一个例子,它传递两个实参给相关联的代码块,值得注意的是,这个迭代器实现在内部使用了另一个迭代器:

    def circle(r,n)
    n.times do |i| # Notice that this method is implemented with a block
        angle = Math::PI * 2 * i / n
        yield r*Math.cos(angle), r*Math.sin(angle)
    end
    end
    # This invocation of the iterator prints:
    # (1.00, 0.00) (0.00, 1.00) (-1.00, 0.00) (-0.00, -1.00)

    使用yield关键字的确很像调用一个方法,围绕参数的圆括号是可选的,但是,他和方法调用的不同之处在于不能在yield表达式后面接代码块,你不能将一个代码块传递给另一个代码块。

    如果一个方法在调用时没有相关联的代码块,那么在定义该方法时使用yield就是错误的,因为在这种情况下,将没有什么可以作为yield的目标。有时候你希望编写这样一个方法:当有相关联的代码块时就使用yield,否则将采取一些默认行为(而不是抛出一个错误)。为了做到这一点,你可以使用block_given?方法判断是否在调用该方法时带有一个代码块。block_given?及它的同义词iterator?都是Kernel的方法,因此他们表现的像全局函数一样。

    # Return an array with n elements of the form m*i+c
    # If a block is given, also yield each element to the block
    def sequence(n, m, c)
       i, s = 0, [] # Initialize variables
      while(i < n) # Loop n times
        y = m*i + c # Compute value
       yield y if block_given? # Yield, if block
       s << y # Store the value
      i += 1
    end
    s # Return the array of values
    end

    sequence(3,5,1) { |y| puts y}

    s= sequence(3,5,1)
    s.each { |x| print x}

    一个枚举器必须是一个Enumerable对象,其目的在于枚举其他的对象。

    range

    A..Z 范围提供了to_a,可以转成数组

    ('A'..'Z').to_a.each{|letter| print letter}

    检验是否属于某个范围

    puts ('A'..'Z').include?('r')

    还可以把范围当做数组的索引,一次选择多个元素


    a=[2,4,6,8,10]
    puts a[1..3]

    参考:《ruby programming》

  • 相关阅读:
    java-mybaits-00503-延迟加载
    java-mybaits-00502-案例-映射分析-一对一、一对多、多对多
    java-mybaits-00501-案例-映射分析-订单商品数据模型
    java-mybaits-00402-Mapper-动态sql-if、where、foreach、sql片段
    数据结构与算法实验题7.1 M 商人的求救
    HDOJ 1075
    HDOJ 1856
    HDOJ 3790
    HDOJ 1869
    HDOJ 1870
  • 原文地址:https://www.cnblogs.com/youxin/p/3824251.html
Copyright © 2011-2022 走看看