编写自定义的迭代器

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》

ruby迭代器iterator和枚举器Enumerator的更多相关文章

  1. Java中的迭代迭代器Iterator与枚举器Enumeration

    Iterator 和 Enumeration区别 Iterator 和 Eumberation都是Collection集合的遍历接口,我们先看下他们的源码接口 package java.util; p ...

  2. Ruby迭代器(Iterator)

    简单的讲,一个迭代器就是一个能接受代码块的方法.当初为了进行迭代操作而设置了带块方法,现在很多时候仍然称它为迭带器. 可实际上,早期版本的 Ruby 将使用代码块的方法称为迭代器,因为它们就是被设计来 ...

  3. C#图解教程 第十八章 枚举器和迭代器

    枚举器和迭代器 枚举器和可枚举类型 foreach语句 IEnumerator接口 使用IEnumerable和IEnumerator的示例 泛型枚举接口迭代器 迭代器块使用迭代器来创建枚举器使用迭代 ...

  4. C#知识点-枚举器和迭代器

    一.几个基本概念的理解 问题一:为什么数组可以使用foreach输出各元素 答:数组是可枚举类型,它实现了一个枚举器(enumerator)对象:枚举器知道各元素的次序并跟踪它们的位置,然后返回请求的 ...

  5. C#-14 枚举器和迭代器

    一 枚举器和可枚举类型 当我们为数组使用foreach语句时,这个语句为我们依次取出了数组中的每一个元素. var arrInt = new int[] { 11, 12, 13, 14 }; for ...

  6. C#中的枚举器(转)

    术语表 Iterator:枚举器(迭代器) 如果你正在创建一个表现和行为都类似于集合的类,允许类的用户使用foreach语句对集合中的成员进行枚举将会是很方便的.这在C# 2.0中比 C# 1.1更容 ...

  7. C#中的枚举器

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年6月28日. 一.先从可枚举类型讲起 1.1 什么是可枚举类型? 可枚举类型,可以简单的理解为: 有一个类,类中有挺多的数据,用一种统 ...

  8. 关于IEnumerator<T>泛型枚举器 和 IEnumerable<T>

    在开发中我们经常会用到 IEnumerable<T> xxx 或者 List<T> xxx 这种集合或者集合接口,实际上就是一个线性表嘛然后结合C#提供的语法糖 foreach ...

  9. ruby中迭代器枚举器的理解

    参考<ruby编程语言>5.3迭代器和可枚举对象 迭代器一个迭代器是一个方法,这个方法里面有yield语句,这个方法里的yield语句,与传递给这个方法的块进行数据传输 yield将数据传 ...

随机推荐

  1. struts2学生信息管理系统篇章②进度报告篇章

    之前做这个系统的时候是什么都不懂的! 经过一个月的时间,慢慢的java的知识都捡起来了. 对struts2和mvc模式都有一一定程度的了解,汇报一下上次的进度. 这个系统我所有的功能中我暂时只做到了下 ...

  2. 浅析ASP.NET的状态保持

    ASP.NET的状态保持:1.viewstate:隐藏域,记录服务器端控件的状态,适用于页面不关闭的情况下多次与服务器交互,页面自己给自己传值:文本框的改变事件.IspostBack也依赖viewst ...

  3. dbms_job和dbmsi_job

    工作中可能遇到这样的情况,在A用户下有一个不用的job,但是dba不知道A用户的密码,怎么删除这个job呢.   相信大部分人都会尝试在sys用户下用dbms_job.remove()命令去删除它,但 ...

  4. iOS9 http不能访问网络——在Xcode中将https改成http方式

    =====================2016-01-29更新=========================== 最近做demo时,发现将https改成http方式略有小变 1. 没有改成ht ...

  5. Excel对话框大全

    Excel对话框大全 序号 名称 描述 1 Application.Dialogs(1).Show 是调用打开对话框  2 Application.Dialogs(5或145).Show 是调用另存为 ...

  6. 10.14_魅族手机音乐播放无故暂停,MetroUICss-tile中的字如何居中

    (1)魅族手机,播放音乐,无故暂停.不管是自带的音乐播放程序,还是下载的其他音乐播放器都是如此.而且,手机上有个Google服务耗电量非常高,会经常弹出登陆Google账号的弹出项. (2)Metro ...

  7. 03_MySQL中文乱码处理_01_MySQl数据库字符集知识

    [MySql数据库常见字符集介绍] 在互联网环境中,使用MySql时常用的字符集有: [如何选择合适的字符集] 1.如果处理各种各样的文字,发布到不同语言的国家地区,应选Unicode字符集,对MyS ...

  8. identifier not found error on function call

    在C++工程中,自定义一个方法 void fgetsDemo(),在main 方法中调用,源代码如下: #include "stdafx.h" #include <stdio ...

  9. AOP学习过程中遇到的问题汇总

    jdk版本问题:     在spring较低的版本中,仅支持jdk1.5到1.7版本,由于我本机安装的是jdk1.8,所以在调试的时候就会提示jdk版本要高于1.5.于是换成spring4.0,在co ...

  10. HTTP_USER_AGENT

    <!DOCTYPE html><html><head><meta charset="UTF-8" /><title>We ...