Это 2я статья из серии «Ruby и красивый код».
Ruby и красивый код #1
Задача №1 по высокоуровневому программированию (ФГОУ ДПО МЭТТ ГАИ)
Эта задача использовались автоматизированной системой тестирования при проведении контрольных работ по предметам: «Программирование на языке высокого уровня» и «Программное обеспечение компьютерных сетей» в 2006-2007 учебном году.
Задача: Дан целочисленный массив. Необходимо вывести вначале его элементы с четными индексами, а затем — с нечетными.
Решение #1
arr = (1..9).to_a
indexes, p, np = [], [], []
arr.each_index{|i| indexes << i}
for i in indexes
if i % 2 == 0
p << i
else
np << i
end
end
for i in p
puts arr[i]
end
puts "---"
for i in np
puts arr[i]
end
Решение #2
arr = (1..9).to_a
arr.each_with_index do |elem, index|
puts elem if (index % 2) == 0
end
arr.each_with_index do |elem, index|
puts elem if (index % 2) != 0
end
Решение #3 - Немного измененное решение #2
arr = (1..9).to_a
n, np = [], []
arr.each_with_index do |elem, index|
if (index % 2) == 0
p << elem
else
np << elem
end
end
puts p
puts "---"
puts np
Первое решение задачи - решение человека, не знающего о существовании метода each_with_index (мое). Второе решение - решение моего друга, который значительно более опытный програмист чем я и который знает о существовании метода each_with_index (Максим, спасибо!). Третье решение - мое, его я создал для решения некоторых недостатков решения номер 2, а именно: вместо двух обходов по массиву теперь остался лишь один, кроме того значения под парными и непарными индексами не просто выводятся на экран, но и сохраняются в соответствующие масивы p и np для возможности их дальнейшего использования.
Выводы: Первое решение можно отнести к over engineering, так как в нем слишком много кода, что связано с малым опытом работы на языке Ruby. Второй метод наиболее лаконичный и читабельный, а третий найдет большее применение.
Создаем себе Золотое правило: Прежде, чем писать код, следует убедиться в том, что метода реализующего полностью или частично необходимую функциональность, нету. Спешка и нежелание работать с документацией - большие враги программиста!
Обновление #1:
Вот придумал еще один интересный способ решения:
arr = (1..9).to_a
p, np = [], []
arr.each_index do |i|
i%2 == 0 ? p << i : np << i
end
puts arr.values_at(*p)
puts arr.values_at(*np)
Обновление #2:
Максим предоставил еще более изящный вариант решения задачи:
arr = (1..9).to_a
even_indexes, odd_indexes = (0..(arr.size - 1)).partition {|i| i % 2 == 0}
puts arr.values_at(*even_indexes)
puts arr.values_at(*odd_indexes)
Браво!