你可以使用的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',這是我用於回答的慣例。 –