你可以使用的cycle和Enumerator组合:
class Range
def multi_step(*steps)
a = min
Enumerator.new do |yielder|
steps.cycle do |step|
yielder << a
a += step
break if a > max
end
end
end
end
p (1..20).multi_step(2, 4).to_a
#=> [1, 3, 7, 9, 13, 15, 19]
注意,第一个元素是1,因为(1..20).step(2)
第一个元素也为1
这需要exclude_end?
考虑:
p (1...19).multi_step(2, 4).to_a
#=> [1, 3, 7, 9, 13, 15]
而且可以偷懒:
p (0..2).multi_step(1,-1).first(20)
#=> [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
p (0..Float::INFINITY).multi_step(*(1..100).to_a).lazy.map{|x| x*2}.first(20)
#=> [0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380]
这里是FizzBuzz一个变种,它产生的3或5所有的倍数而不是15:
p (3..50).multi_step(2,1,3,1,2,6).to_a
#=> [3, 5, 6, 9, 10, 12, 18, 20, 21, 24, 25, 27, 33, 35, 36, 39, 40, 42, 48, 50]
应该是第一个元素? '1'还是'3'? '(1..20).step(2)'是'1',这是我用于回答的惯例。 –