Search code examples
rubyarrayschunking

Getting start index of chunks as part of result when chunking Ruby array


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.


Solution

  • 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]]]