Enumerator迭代

Mix-in Enumerator获得的迭代方法:

* each_cons <https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogeachcons>


* each_slice
<https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogeachslice>:

* each_with_index
<https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogeachwithindex>:

* with_index
<https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogwithindex>:

* each_with_object
<https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogeachwithobject>:

* each_entry
<https://www.cnblogs.com/f-ck-need-u/p/10709707.html#blogeachentry>:
<>

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

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信