假设我有一个@lines集合,我想对它进行迭代,但是我想根据集合的内容来操作它的迭代方式,我是如何做到的呢?
也就是这样的东西:
@lines.each_with_index do |line, index|
if (index % 3 = 0)
jump_to index == next_multiple_of_3
end
end所以看起来是这样的:
Element | Index
a | 1
b | 2
c | 3
f | 6
g | 7
h | 8
i | 9
l | 12我怎么能这么做?
编辑1
注意,正如我在下面的评论中解释的那样,我不一定总是想跳转到特定的倍数。基本上,我想跳到一些由当前迭代中发生的事情决定的任意索引。
所以第一圈,它可以跳过3指数,但是下一次它跳过7指数,接下来的5次,它像往常一样按1跳,然后按2指数跳起来。
唯一的常量是根据当前迭代块中发生的事情来确定它在原始迭代过程中的进展方式。
发布于 2017-03-14 07:55:21
使用while循环并自己管理索引。我们多年来一直在劝阻人们不要这样做。但这是一个合适的案例。:)
idx = 0
while idx < @lines.length
line = @lines[idx]
idx += condition ? x : y # or whatever logic you have
end当然,这假定@lines能够进行随机访问。如果不是,那就把它做成数组。
发布于 2017-03-14 11:09:22
如果要多次使用此逻辑,则可能需要定义一个可枚举的方法:
module Enumerable
def skip
Enumerator.new do |yielder|
skip_count = 0
each_with_index do |object, index|
if skip_count > 0
skip_count -= 1
else
yielder << object
skip_count = yield(object, index) || 0
end
end
end
end
end您可以在任何Enumerable上使用它,并且可以根据当前元素和索引指定应该跳过的元素数。
对于您的示例,您希望跳过2个元素(例如,4个和5个元素),每6个元素跳过一次。不过,有一个选项,您希望跳过index = 2之后的元素(Ruby是基于0的):
puts ('a'..'z').skip{ |_, index| 2 if (index - 2) % 6 == 0 }.take(8)
# a
# b
# c
# f
# g
# h
# i
# l发布于 2017-03-14 08:03:06
人们可以使用临时累加器来完成这个任务:
@lines = (1..12).map(&:to_s)
JUMP_BY = 3
@lines.each.with_index.reduce(0) do |acc, (line, index)|
next acc unless index == acc
puts "line: #{line}"
q, mod = index.divmod(JUMP_BY)
(mod == JUMP_BY - 1) && (q % 2).zero? ? \
(q + 2) * JUMP_BY - 1 : index + 1 # next
end
#⇒ line: 1
# line: 2
# line: 3
# line: 6
# line: 7
# line: 8
# line: 9
# line: 12通过使JUMP_BY成为一种方法,可以根据需要实现复杂的决策。
https://stackoverflow.com/questions/42780083
复制相似问题