each_cons(3)
извлекает три смежных термина, необходимых для проверки среднего, исключая тройки с первым или последним элементом array
в середине.
with_index(1)
учитывает тот факт, что триплет с первым элементом, равным array
в середине, был пропущен, поэтому нумерация индексов начинается с 1.
Вы не определили, что вы подразумеваете под пиками и впадинами. Если вы хотите взять локальные значения max и min, то сработает следующее.
array.each_cons(3).with_index(1).select{|a, i| a.max == a[1]}.map(&:last)
# => [1, 5]
array.each_cons(3).with_index(1).select{|a, i| a.min == a[1]}.map(&:last)
# => [4, 7]
Или, если вы имеете в виду то, что Стефан объясняет в комментарии к моему ответу, тогда сработает следующее:
array
.each_cons(3)
.with_index(1)
.select{|(a1, a2, a3), i| a1 < a2 && a2 > a3}
.map(&:last)
# => [1, 5]
array
.each_cons(3)
.with_index(1)
.select{|(a1, a2, a3), i| a1 > a2 && a2 < a3}
.map(&:last)
# => [4, 7]