Ruby 跳过';n';可枚举#每个#cons中的迭代

Ruby 跳过';n';可枚举#每个#cons中的迭代,ruby,Ruby,在执行每个块时,是否可以跳过n迭代 persons.each_cons(2) do |person| if person[0] == person[1] #SKIP 2 iterations end puts "Howdy? #{person[0]}" end 你不能直接这么做 您可能希望调用数组,或者如果顺序很重要,请查看新方法: 另一种方法是使用each迭代器,这种方法并不真正像ruby persons = [1,1,2,2,2,3,4,4,5,5,6,7,8,9]

在执行
每个
块时,是否可以跳过
n
迭代

persons.each_cons(2) do |person|
  if person[0] == person[1]
    #SKIP 2 iterations
  end

  puts "Howdy? #{person[0]}"
end

你不能直接这么做

您可能希望调用数组,或者如果顺序很重要,请查看新方法:


另一种方法是使用
each
迭代器,这种方法并不真正像ruby

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

只需显式使用
枚举器即可:

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


一些注意事项:

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(意外惊喜)营救
    停止迭代
    ,使
    下一步
    ing超级容易
  • 显式使用
    枚举器
    是一种非常好的方法!抓取一本Ruby Pickaxe书籍的最新版本,浏览第4.3章(块和迭代器),尽情享受吧
  • 不要错过平行作业,即使是在区块中
  • 如果您无法按所需方式浏览
    可枚举的
    ,我建议您花10分钟阅读模块文档:许多人可能会发现
    #每个cons
    #每个片段
    之间的差异与我一样具有启发性。
    特别是,至少要检查所有以
    chunk
    drop
    每个
    slice
    开头的方法名称(欢迎在评论中提供更多建议!)。必须手动调用
    #next
    的情况实际上很少

奖励积分:

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
了解“迭代器”和
枚举器之间的区别(与上面提到的鹤嘴锄章节相同)实际上很有用。
有时,构建自定义迭代器可以更好地解决您的难题:

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公开元素枚举而不是列表迭代的方式可以改变您对序列和集合的思考方式——给它一个机会;)

使用
uniq
不是一个选项,因为
persons
是一个数组数组(CSV),其中一些列是日期时间值,因此没有两行完全相同。你能详细说明第二种方法吗?(如何/做什么)脚注:的免费在线版本是针对Ruby 1.6的,没有提供所提到的“迭代器”、“枚举器”
可枚举的深入讨论。