2016-09-21 3 views
2

У меня есть массив, который состоит из конкатенированных множеств инкрементных (+1) последовательностей. Вот пример с тремя последовательностями:Возвращает первый и последний элемент в последовательностях

sequences = [2,3,4,7,12,13,14,15] 

Я пытаюсь получить первый и последний элемент каждой последовательности и возвращает массив с этими значениями. Из приведенного выше массива, результат должен выглядеть следующим образом:

[[2,4][7,7][12,15]] 

Я пришел с этим довольно наивным решением, которое я думал, что буду работать, но он возвращает только первую последовательность. Любая идея почему? И/или любое предложение лучшего решения в целом?

new_array = [] 
start_point = sequences[0] 
end_point = sequences[0] 

sequences.map do |element| 
    if element == end_point + 1 
    end_point = element 
    elsif element == end_point 
    next 
    else 
    new_array << [start_point, end_point] 
    startpoint = element 
    end_point = element 
    end 
end 
return new_array 
+1

Вы заслуживаете бонусных баллов за то, что думаете в C, но пишите в Ruby! Однако делать это в Ruby часто приводит к ужасно неэффективному коду. Вместо этого, когда это возможно, используйте встроенные методы функционального программирования-esque, такие как 'map',' inject', 'tap' и' select'. Все эти методы реализованы на C, поэтому интерпретатору значительно меньше приходится выполнять при выполнении вашего алгоритма. – Sean

ответ

5

Вы можете использовать chunk_while найти порядковые номера: (это также пример в документации)

sequences.chunk_while { |i, j| i + 1 == j }.to_a 
#=> [[2, 3, 4], [7], [12, 13, 14, 15]] 

И map вместе с values_at для извлечения каждого суб-массива первый и последний элемент:

sequences.chunk_while { |i, j| i + 1 == j }.map { |a| a.values_at(0, -1) } 
#=> [[2, 4], [7, 7], [12, 15]] 

Или более многословен:

....map { |a| [a.first, a.last] } 
Смежные вопросы