Ruby и красивый код #2
ноября 18, 2010 | Published in Ruby, Основы
Это 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)
Браво!