n
执行块时是否可以跳过迭代each
?
persons.each_cons(2) do |person|
if person[0] == person[1]
#SKIP 2 iterations
end
puts "Howdy? #{person[0]}"
end
n
执行块时是否可以跳过迭代each
?
persons.each_cons(2) do |person|
if person[0] == person[1]
#SKIP 2 iterations
end
puts "Howdy? #{person[0]}"
end
只需Enumerator
明确使用:
persons = [1, 2, 1, 1, 1, 3]
enum = persons.each_cons(2)
loop do
p1, p2 = enum.next
if p1 == p2
2.times { enum.next }
else
puts "Howdy? #{p1}"
end
end
一些注意事项:
while
, for
, )已经通过ing 进行loop
救援(惊喜惊喜),使ing 超级容易StopIteration
break
next
Enumerator
is 和 Ruby 一样!拿一本最新的 Ruby Pickaxe 书,浏览到第 4.3 章(块和迭代器),尽情享受吧!Enumerable
发现两者之间的区别#each_cons
和启发性。
特别是,请至少查看所有以 、 和 开头的方法名称(欢迎在评论中提出更多建议!)。不得不手动调用实际上很少见。#each_slice
chunk
drop
each
slice
#next
奖励积分:
了解“迭代器”和(与上面提到的 Pickaxe 相同的章节)之间的区别Enumerator
实际上会派上用场。
有时通过构建自定义迭代器可以更好地解决您的难题:
persons = [1, 2, 1, 1, 1, 3]
custom_iter = Enumerator.new do |yielder|
en = persons.each_cons(2)
loop do
2.times { en.next } while (p1, p2 = en.next).reduce(:==)
yielder.yield p1
end
end
custom_iter.each { |pers| puts "Howdy? #{pers}" }
为什么要学习自定义迭代器?想象一下,您需要对任意大的(注意#lazy
)偶数集进行操作:
def Integer.even from:0
Enumerator.new do |yielder, n: (from.even? ? from : from+1 )|
loop { yielder.yield n; n += 2}
end.lazy
end
p Integer.even(from: 3).take(10).to_a
Ruby 公开元素枚举而不是列表迭代的方式可以改变您对序列和集合的看法——给它一个机会;)
另一种与 ruby 不同的方法是使用each
迭代器。
persons = [1,1,2,2,2,3,4,4,5,5,6,7,8,9]
persons_iterator = persons.each
begin
while first_person = persons_iterator.next do
second_person = persons_iterator.next
if first_person == second_person
persons_iterator.next.next # Skip 2 iterations
end
puts "Howdy? #{first_person}"
end
rescue StopIteration
# Iterator end
end