Rubyrush: Циклы в языке Ruby, циклы for in и особенности работы с ними

Ruby для новичков [Rubyrush]

Очень ждал сегодняшнюю тему, потому что очень не хватает понимания механики работы повторов. Например, как реализовать возврат к началу программы, если ввели не корректные данные, или как повторить несколько раз одно и то же действие без копипаста блока кода и так далее.

Сегодня мне расскажут что такое циклы, а так же о том, как работать с переменными и массивами в цикле.

Что такое цикл — это многократное исполнение сценария. Циклом можно назвать любой набор инструкций или команд, которые повторяются несколько раз.

В реальном программировании — на практике, циклы в основном используются для перебора массивов.

Как в Ruby создаётся цикл

Существует два способа создания цикла:

for in — специальный цикл (профильный) созданный для работы с массивами — перебор, сортировка и т п.

array = [1,2,3,4,5]

for item in array do
  puts item
end

while — универсальный цикл, который используется везде кроме перебора массивов.

count = 1

while count <= 5 do
  puts count
  count += 1
  sleep 0.5
end

puts "я иду искать!"

while — во многом похож на оператор if. Аналогичным образом внутри цикла мы проверяем условие. Если условие верное (выполняется) то мы входим в цикл и выполняем команды описанные внутри цикла.

Как только проверочное условие перестанет выполняться — происходит выход из цикла и программа продолжает свою работу по сценарию, указанному после цикла (если он есть).

Помнится мне что в JS с циклами все примерно так же было.

Значит итого у нас получается что цикл while состоит из условия цикла — проверочной части и тела цикла — основной чести, в которой содержится основной сценарий работы цикла.

Перебор массива циклом for in

Для того что бы осуществить перебор массива при помощи цикла for in нам потребуется сам массив, который будем перебирать, а так же две вспомогательные переменные. В одну переменную мы будем собирать те элементы массива, которые нам нужны, а во второй переменной мы сохраним счётчик, показывающий…

Далее пишем цикл в котором указываем промежуточную переменную, которая нам потребуется в качестве временного хранилища. Имя временной переменной не должно пересекаться с другими переменными. Временное хранилище используется только внутри цикла — в теле цикла. Между do и end.

eggs = [1, 0, 0, 0, 0, 2, 22, 32, 0, 1, 21, 0, 222, 54, 0, 6, 0, 7, 54, 0, 8, 4, 3]

good_egs = []
broken_count = 0

for item in eggs do
  
end

После того как мы запустим программу, цикл будет поочерёдно брать по одному элементу из массива и присваивать его временной переменной item, для того что бы проверить данные на условия сортировки, которые мы зададим.

Условия находятся в теле цикла, т е после do.

eggs = [1, 0, 0, 0, 0, 2, 22, 32, 0, 1, 21, 0, 222, 54, 0, 6, 0, 7, 54, 0, 8, 4, 3]

good_egs = []
broken_count = 0

for item in eggs do
  if(item != 0)
    broken_count += 1
  else
    good_egs << item
  end
  
end

В условии мы пишем, что если элемент массива НЕ РАВЕН 0, то мы увеличиваем счётчик битых яиц на единицу:

if(item != 0)
    broken_count += 1

В остальных случаях мы сохраняем этот элемент массива в другой массив при помощи утиных лапок <<

else
    good_egs << item
  end

После цикла мы выводим данные, для большей наглядности, дополняя их текстом.

Итоговая программа выглядит следующим образом

eggs = [1, 0, 0, 0, 0, 2, 22, 32, 0, 1, 21, 0, 222, 54, 0, 6, 0, 7, 54, 0, 8, 4, 3]

good_egs = []
broken_count = 0

for item in eggs do
  if(item != 0)
    broken_count += 1
  else
    good_egs << item
  end
  
end

puts "У нас было яиц: " + eggs.size.to_s + " шт."
puts "Мы их перебрали и теперь"
puts "Целые яйца: " + good_egs.size.to_s + " шт."
puts "Битые яйца: " + broken_count.to_s + " шт."

Главные правила при работе с циклами

При работе с циклами важно соблюдать два правила:

  • ВСЕГДА инициализируй переменную ДО цикла. В противном случае цикл не запустится.
  • ВСЕГДА проверяйте условия проверки работы цикла. Оно выступает в качестве ограничителя. И оно не должно выполняться всегда! В противном случае ваш цикл никогда не остановится, потому что не будет иметь ограничений.

Слепой цикл — цикл, который самостоятельно не остановится, потому что у него нет правильно заданных условий, или условие выполняется всегда.

Пример программы использующей оба варианта циклов

Пишем игру «Кто такая Элис». По условиям игры мы создаём массив с именами людей. Затем создаём цикл, который на входе будет получить элементы массива — те самые имена и на выходе будет здороваться с каждым человеком используя его имя.

Но как только в цикл попадает имя Эллис, программа должна задать ей несколько вопросов, целью которых является необходимость выяснить кто же такая, эта Элис.

Начнём написание программы с создания пустого массива, который сохраним в переменную и еще одной переменной, в которую будем сохранять имена, которые вводит пользователь.

names = []
user_imput = nil

Ниже пишем цикл while в котором прописываем правила наполнения массива именами. Спрашиваем у пользователя его имя и после того как он его вводит — сохраняем это имя в наш массив. ну и конечно же обрезаем пробел в конце при помощи метода chomp.

while user_imput != "" do
  user_imput = get.chomp
  names << user_imput
end

Затем пишем второй цикл, который будет сортировать наш массив с именами. Цикл будет поочерёдно брать по одному имени, и выводить строку: » С нами, ИМЯ человека». Но как только цикл получит имя Элис — он удивится и сразу же начнёт задавать вопросы, как в песенке. После чего программа завершит свою работу.

for item in names do
  puts "С нами #{item}"
  sleep 1

  if (item == "Элис")
    puts "#{item}? А кто такая #{item}?"
    sleep 1
    break
  end
  
end

В завершении я немного добавил ясности при помощи дополнительных строк с текстом. А то в начале запуска программы было не понятно что она ждет от пользователя )

names = []
user_imput = nil

puts "Привет! Начинайте вводить имена гостей ,а как закончите - просто введите пустую строку, что бы перейти к перебору гостей ;)"

while user_imput != "" do
  user_imput = gets.chomp
  names << user_imput
end

for item in names do
  puts "С нами #{item}"
  sleep 1

  if (item == "Элис")
    puts "#{item}? А кто такая #{item}?"
    sleep 1
    break
  end
  
end

puts "Что это за девочка и где она живет?"
sleep 1
puts "А вдруг она не курит? А вдруг она не пьёт?"
sleep 1
puts "А мы с такими рожами возьмем да и припрёмся к Элис... :)"

Команда break

Эта команда используется для выхода из цикла. Особенно это актуально если вы не хотите дожидаться начала новой итерации цикла, для проверки условий цикла.

Юрий Ронин