Ruby Enumerator的各种迭代
Enumerator迭代
Mix-in Enumerator获得的迭代方法:
each_cons()
each_cons(n) { ... } → nil
each_cons(n) → an_enumerator
迭代容器中的每个元素,都从其开始向后取连续n个元素组成一个数组传递到语句块中。
(1..10).each_cons(3) { |a| p a }
## 输出:
=begin
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
=end

each_slice()
each_slice(n) { ... } → nil
each_slice(n) → an_enumerator
每次从容器中取出3个n个元素组成数组传递到语句块中。
(1..10).each_slice(3) { |a| p a }
## 输出:
=begin
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]
=end
each_with_index()
each_with_index { |obj, i| block } → enum
each_with_index → an_enumerator
迭代容器每个元素,将元素和其对应的index传递给语句块中的两个变量。
hash = Hash.new
%w(cat dog wombat).each_with_index { |item, index|
hash[item] = index
}
hash # {"cat"=>0, "dog"=>1, "wombat"=>2}
with_index()
e.with_index(offset = 0) {|(*args), idx| ... }
e.with_index(offset = 0)
迭代容器每个元素,将元素和对应的index传递给语句块中的两个变量。可以指定参数offset,使得传递给语句块的index变量从offset开始(即传递每个原始index加上offset后的值)。默认,offset=0,等价于each_with_index。
a = %w(a b c d e)
a.each.with_index do |x,idx|
p "index: #{idx}, value: #{x}"
end
## 输出:
=begin
"index: 0, value: a"
"index: 1, value: b"
"index: 2, value: c"
"index: 3, value: d"
"index: 4, value: e"
=end
a.each.with_index(2) do |x,idx|
p "index: #{idx}, value: #{x}"
end
## 输出:
=begin
"index: 2, value: a"
"index: 3, value: b"
"index: 4, value: c"
"index: 5, value: d"
"index: 6, value: e"
=end
each_with_object()
each_with_object(obj) { |(*args), memo_obj| ... } → obj
each_with_object(obj) → an_enumerator
实现类似于reject/reduce的功能。迭代每个元素,然后将元素传递给语句块中的变量,于此同时,还会指定一个obj参数对象作为memo_obj变量的初始值,最后经过语句块的操作之后,返回obj最初引用的对象。
必须注意,obj应该传递可变对象,并保证在语句块中没有改变obj对象的引用,否则each_with_object将总是返回初始值。见下面示例分析。
evens = (1..10).each_with_object([]) { |i, a| a << i*2 }
#=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
上面的例子中,迭代Range容器中的每个元素并将之传递给语句块中的变量i,同时传递一个初始空数组对象给语句块中的变量a,这就像是在语句块中初始化了一个空数组。然后,每次迭代过程中都将i乘2后放入数组的尾部。最后返回这个数组对象a。
再比如下面的例子中,传递初始字符串对象"x",两个语句块都将每次迭代的字母追加到这个字符串对象的尾部,但是结果却不同。
a = ("a".."c").each_with_object("x") {|i,str| str += i}
b = ("a".."c").each_with_object("x") {|i,str| str << i}
p a # "x"
p b # "xabc"
这是因为,虽然str += i每次都会创建新的对象并赋值给str,使得str从引用原有的字符串对象"x"改变为引用另一个新对象,每次迭代都会改变引用目标,使得最后返回时,只能返回最初始的字符串对象"x"。
而str << i的方式是直接在原字符串上追加字母的,str所引用的对象一直都未改变,最后返回的原始对象也是更改后的。
而对于数值对象来说,它是不可变对象,意味着操作这个对象一定会返回一个新对象,而且下面也使用sum += i的方式,它本身就是返回新对象的。于是,下面的例子将总是返回初始数值对象0。
a = (1..10).each_with_object(0) {|i, sum| sum += i}
p a # 0
要实现数值相加,可以使用reduce/inject()来实现。
a = (1..10).inject(:+)
p a # 55
a = (1..10).inject {|sum, x| sum + x}
p a # 55
each_entry()
传递容器中每个元素给语句块,并从语句块中yield一个新数组返回。
class Foo
include Enumerable
def each
yield 1
yield 1, 2
yield
end
end
Foo.new.each_entry{ |o| p o }
## 输出:
=begin
1
[1, 2]
nil
=end
Ruby Enumerator的各种迭代的更多相关文章
- ruby Enumerator::lazy
当一个很大的数组或集合需要做循环操作的时候,一次性把数据放到内存会有很大弊端.这时lazy就派上用场了.Float::INFINITY 是无穷大意思 举个例子 取出1到无穷大对7整除余数为0的前10个 ...
- Ruby系列文章
安装Ruby.多版本Ruby共存.Ruby安装慢问题 Ruby语言的一些杂项 Ruby中的常量:引号.%符号和heredoc Ruby中的数值 Ruby字符串(1):String基本用法 Ruby字符 ...
- Ruby小白入门笔记之<个人记录档>
书写缘由 快两年的JAVA开发,因为来到一家新公司,产品需要用Ruby开发,故此才有了这从头开始,一入编程深似海啊...... 因为入门时是JAVA,所以理念跟规范早已形成,故此感觉突然采用Ruby编 ...
- ruby迭代器iterator和枚举器Enumerator
编写自定义的迭代器 The defining feature of an iterator method is that it invokes a block of code associatedwi ...
- ruby迭代起基础
“循环”会用在程序中的各种地方.而在循环的地方善用“迭代器”,则是熟练进行Ruby程序设计的重要关键. 不过,迭代器确实有比较抽象的地方,语法也有点怪异(尤其是yield的用法),光是依靠文字说明.看 ...
- 使用 Capistrano 和写作 Ruby 迭代边缘部署
想边自己写ruby代码,边部署随时能够到处查看,heroku域名又不友好,速度在国内又慢.于是乎想起来capistrano,于是学起 ... capistrano 一点入门认知 https://www ...
- javascript语言扩展:可迭代对象(5)
文章1-4篇说的都是js中的可迭代对象,下面让我们看看ruby中的等价物. 不可否认,ruby中对于迭代器和生成器的语法都相当简洁:ruby从一开始就有一个简洁的基因,而js后来的不断扩充使得其有些语 ...
- Ruby数组(1):基本用法
数组 Ruby中的数组是一个容器,数组中的每个元素都是一个对象的引用. 注意,Array类中包含了Enumerable模块,所以Enumerable中的方法也都能使用,例如Enumerable中的re ...
- Ruby数组方法整理
数组方法整理 方法列表: all().any().none()和one():测试数组中的所有或部分元素是否满足给定条件.条件可以是语句块中决定,也可以是参数决定 append():等价于push() ...
随机推荐
- 封装ajax原理
封装ajax原理 首先处理 用户如果不传某些参数,设置默认值 type默认get 默认url为当前页 默认async方式请求 data数据默认为{} 处理用户传进来的参数对象 遍历,拼接成key=va ...
- springboot-项目获取resources下文件碰到的问题(classPath下找不到文件和文件名乱码)
项目是spring-boot + spring-cloud 并使用maven 管理依赖.在springboot+maven项目下怎么读取resources下的文件实现文件下载? 怎么获取resourc ...
- js的七大设计原则--迪米特原则
一.什么是迪米特原则 迪米特原则也叫最少知道原则,一个类应该对其他对象保持最少的了解.通俗来讲,就是一个类对自己依赖的类知道的越少越好.因为类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另 ...
- window server 2008 安装Oracle10g
oracle安装都大同小异. 开始安装步骤 输入完之后点击下一步 这时候稍等一会儿. 这时候也要稍等一会儿. 直接安装. 设置口令管理,设置SCOTT的密码为tiger就好了. 这时候稍等一会儿. o ...
- Pycharm画五角星
import turtle turtle.setup(600,400,0,0) turtle.bgcolor('red') turtle.color('yellow') turtle.fillcolo ...
- 安卓开发学习笔记(五):史上最简单且华丽地实现Android Stutio当中Webview控件https/http协议的方法
一.我们先在XML当中自定义一个webview(Second_layout.xml) 代码如下: <?xml version="1.0" encoding="utf ...
- 吴恩达机器学习笔记53-高斯分布的算法(Algorithm of Gaussian Distribution)
如何应用高斯分布开发异常检测算法呢? 异常检测算法: 对于给定的数据集
- [Swift]LeetCode78. 子集 | Subsets
Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solut ...
- [Swift]LeetCode989. 数组形式的整数加法 | Add to Array-Form of Integer
For a non-negative integer X, the array-form of X is an array of its digits in left to right order. ...
- Python面试真题第四节
81.举例说明SQL注入和解决办法 82.s="info:xiaoZhang 33 shandong",用正则切分字符串输出['info', 'xiaoZhang', '33', ...