Takes an Array and turns consecutive integers into Range objects.
class Array
def collapse_ranges
return self if self.length <= 2
self.uniq!
self.sort! rescue nil
temp_array, return_array = [], []
self.each_with_index do |item, i|
if item.respond_to?(:next)
temp_array.push item
if item.next != self[i + 1]
return_array.concat 3 <= temp_array.length ?
[temp_array.first..temp_array.last] :
temp_array
temp_array.clear
end
else
return_array.concat 3 <= temp_array.length ?
[temp_array.first..temp_array.last] :
temp_array
temp_array.clear
return_array.push item
end
end
return return_array
end
end
>> [1, 3, 4, 5, 7, 8].collapse_ranges.join(', ')
=> 1, 3..5, 7, 8
>> %w(a c d e g i j).collapse_ranges.join(', ')
=> a, c..e, g, i, j
>> [1, 2.5, 3, 4, 5].collapse_ranges.join(', ')
=> 1, 2.5, 3..5
>> [1, 2, 3, 4, {:test => 'value'}, 5].collapse_ranges.join(', ')
=> 1..4, testvalue, 5