Larsenal Larsenal - 10 months ago 40
Ruby Question

How do I summarize array of integers as an array of ranges?

I'd like to take input such as:

[1,2,4,5,6,7,9,13]


and turn it into something like the following:

[[1,2],[4,7],[9,9],[13,13]]


Each sub-array represents a range of integers.

Answer Source

Functional approach using Enumerable#chunk:

xs.enum_for(:chunk).with_index { |x, idx| x - idx }.map do |diff, group|
  [group.first, group.last]
end
# => [[1, 2], [4, 7], [9, 9], [13, 13]] 

How it works: once indexed, consecutive elements in the array have the same x - idx, so we use that value to chunk (grouping of consecutive items) the input array. Finally we just need to take the first and last elements of each group to build the pairs.