I have a situation in which I want to separate an array initialized with nils
into the empty segments and segments containing consecutive runs of numbers.
I found the higher order chunk
function of Array
to provide an elegant solution to this:
<< [nil,nil,1,2,nil,3].chunk { |e| !e.nil? }.each { |e| p e }
>> [false, [nil, nil]]
>> [true, [1, 2]]
>> [false, [nil]]
>> [true, [3]]
However, suppose that I would like the output to also include the starting index into the original array in each chunk, i.e. augmenting the output above to something like:
>> [false, 0, [nil, nil]]
>> [true, 2, [1, 2]]
>> [false, 4, [nil]]
>> [true, 5, [3]]
Is there a solution to obtaining this that retains the expressiveness of the chunk snippet in the above?
Thanks in advance.
A functional modular approach: index the input array, chunk, and map it to the desired output, O(n):
data = xs.each_with_index.chunk { |x, i| !x.nil? }.map do |match, pairs|
[match, pairs.first[1], pairs.map(&:first)]
end
#=> [[false, 0, [nil, nil]], [true, 2, [1, 2]], [false, 4, [nil]], [true, 5, [3]]]