Я ожидаю, что этот вопрос был задан в SO, но ответ не в моем Rolodesk. Однако сделать это достаточно просто.
arr = [1, 2, 3, 5, 6, 7, 8, 10, 12, 13, 14, 17, 18, 20]
arr.slice_when { |x,y| y > x+1 }.
map { |a| a.size == 1 ? a.first : a.first..a.last }
#=> [1..3, 5..8, 10, 12..14, 17..18, 20]
См. Enumerable # slice_when .
Сначала мы вычислим перечислитель
enum = arr.slice_when { |x,y| y > x+1 }
#=> #<Enumerator: #<Enumerator::Generator:0x...0000...fe0>:each>
Мы можем преобразовать enum
в массив, чтобы увидеть элементы, которые будут сгенерированы перечислителем и переданы в map
:
enum.to_a
#=> [[1, 2, 3], [5, 6, 7, 8], [10], [12, 13, 14], [17, 18], [20]]
В качестве упражнения посмотрите, есть ли еще Enumerable метод, который вы могли бы использовать вместо slice_when
. (Подсказка: рассмотрите Великие Дебаты Арахисового масла .)