Circular grill
I have an array with different number of elements 0..n elements. An example would be:
a = [0,1,2,3,4,5,6,7,8,9]
In an iterative process, I would like to move the cursor into the array and cut off the maximum number of elements. If I get to the "end" of the array, it has to start over and select from the beginning:
Something like that:
4.times do |i|
a.slice(i * 3, 3)
end
# i = 0 => [0,1,2]
# i = 1 => [3,4,5]
# i = 2 => [6,7,8]
# i = 3 => [9,0,1]
# ...
However, the last output i = 3
produces [9]
because it .slice
doesn't do exactly what I want.
source to share
You can use Array # rotate and then take the first 3 elements each time:
4.times.each { |i| a.rotate(i*3)[0..2] }
# => [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 0, 1]]
source to share
This may break some code, so be careful.
class Array
alias_method :old_slice, :slice
def slice(o, c)
ret = old_slice(o % size, c)
if ret.size != c
ret += old_slice(0, c - ret.size)
end
ret
end
end
a = [0,1,2,3,4,5,6,7,8,9]
4.times do |i|
p a.slice(i * 3, 3)
end
As Stefan points out, it would be better to give this method a different name, or it might even be better to create a CircularArray class.
class CircularArray < Array
alias_method :straight_slice, :slice
def slice(o, c)
ret = straight_slice(o % size, c)
if ret.size != c
ret += straight_slice(0, c - ret.size)
end
ret
end
end
source to share