Takes an Array and turns consecutive integers into Range objects.
1
2 class Array
3 def collapse_ranges
4 return self if self.length <= 2
5 self.uniq!
6 self.sort! rescue nil
7 temp_array, return_array = [], []
8 self.each_with_index do |item, i|
9 if item.respond_to?(:next)
10 temp_array.push item
11 if item.next != self[i + 1]
12 return_array.concat 3 <= temp_array.length ?
13 [temp_array.first..temp_array.last] :
14 temp_array
15 temp_array.clear
16 end
17 else
18 return_array.concat 3 <= temp_array.length ?
19 [temp_array.first..temp_array.last] :
20 temp_array
21 temp_array.clear
22 return_array.push item
23 end
24 end
25 return return_array
26 end
27 end
1
2 >> [1, 3, 4, 5, 7, 8].collapse_ranges.join(', ')
3 => 1, 3..5, 7, 8
4 >> %w(a c d e g i j).collapse_ranges.join(', ')
5 => a, c..e, g, i, j
6 >> [1, 2.5, 3, 4, 5].collapse_ranges.join(', ')
7 => 1, 2.5, 3..5
8 >> [1, 2, 3, 4, {:test => 'value'}, 5].collapse_ranges.join(', ')
9 => 1..4, testvalue, 5