Получить количество групп
print "Enter the number of groups you would like to create: "
nbr_groups = gets.to_i
При использовании print
вместо puts
отображаемая строка не заканчивается переводом каретки, поэтому, если пользователь вводит, скажем, '4'
, это будет выглядеть так:
Enter the number of groups you would like to create: 4
nbr_groups
возможно более информативно, чем group_number
.
Если вы преобразуете строку в целое число, которое вы наделите chomp
:
"312\n".to_i
#=> 312
по той же причине:
"254my, what a beautiful day it is today".to_i
#=> 254
Создать объект для хранения результатов
Вот некоторые возможности:
nbr_groups = 4 # (say)
arr1 = Array.new(nbr_groups) { [] }
#=> [[], [], [], []]
arr2 = Array.new(nbr_groups) { [] }.unshift('nil')
#=> ["nil", [], [], [], []]
h1 = (1..nbr_groups).each_with_object({}) { |n,h| h[n] = [] }
#=> {1=>[], 2=>[], 3=>[], 4=>[]}
h2 = ("1"..nbr_groups.to_s).each_with_object({}) { |n,h| h[n] = [] }
#=> {"1"=>[], "2"=>[], "3"=>[], "4"=>[]}
Теперь предположим, что мы хотим добавить «Мэри» в группу «2». Мы сделаем это следующим образом:
grp = "2"
arr1[grp.to_i-1] << "Mary"
arr1 #=> [[], ["Mary"], [], []]
arr2[grp.to_i] << "Mary"
arr2 #=> ["nil", [], ["Mary"], [], []]
h1[grp.to_i] << "Mary"
h1 #=> {1=>[], 2=>["Mary"], 3=>[], 4=>[]}
h2[grp] << "Mary"
h2 #=> {"1"=>[], "2"=>["Mary"], "3"=>[], "4"=>[]}
arr2[0]
никогда не используется. Это просто для того, чтобы избежать настройки grp.to_i-1
, необходимой для arr1
. Это немного хаки sh, но я не решаюсь отклонить его, потому что нечто подобное можно найти в ядре Ruby: Дата содержит константу
Date::MONTHNAMES
#=> [nil, "January", "February",..., "December"]
Позволяет Предположим, вы используете arr1
(хотя я мог бы использовать h1
). Чтобы свести к минимуму вероятность путаницы номера группы на основе 1 со смещением массива на основе нуля, я буду относиться к группам как к нулю и выполню настройку на номер группы, когда получен ввод и выводится вывод.
Настройте свой l oop
Я предлагаю использовать Ядро # l oop вместе с ключевым словом break
для всех ваших циклов, если у вас нет хороших причина использовать while
или until
. (Никто не использует for
). Позвольте мне объяснить, почему.
Во-первых, loop
очень гибок. Он может обрабатывать все типы петель. Это также помогает держать код подальше от посторонних глаз, желательной цели кодирования. Предположим, у вас есть код:
x = 1
loop do
x = x + 1
y = 2*x
break if x == 3
end
x #=> 3
y #=> NameError (undefined local variable or method `y' for main:Object)
loop
имеет блок , который начинается с do
и заканчивается end
. Поскольку переменная y
была создана внутри блока, она перестает существовать, когда заканчивается блок. x
, однако, был создан до блока, поэтому он все еще виден после блока.
В отличие от этого, если y
было создано в while
или until
l oop, оно будет виден после конца l oop, потому что эти циклы не являются блоками. Это важное преимущество использования loop
; область действия локальных переменных, созданных в блоке, ограничена блоком.
Еще одна вещь о ключевом слове break
: если за ним следует объект, этот объект возвращается из блока loop
. Пример приведен позже. Более того, если
loop do
...
break 7
...
end
находится в конце метода и выполняется break 7
, метод вернет 7
.
Давайте получим имена и заполните arr
.
grp = -1
loop do
print "Gimme a name: "
name = gets.chomp
break if name.downcase == "stop"
grp = (grp + 1) % nbr_groups
arr[grp] << name
end
Предположим, это было выполнено, когда
nbr_groups #=> 3
и записи были "Ruth"
, "Mary"
, "Bob"
, "Lou"
, "Todd"
, "Bif"
и "Tim"
. Тогда у нас будет:
arr #=> [["Ruth", "Lou", "Tim"], ["Mary", "Todd"], ["Bob", "Bif"]]
Возвращать информацию о группе
Теперь нам нужно многократно запрашивать (основанный на 1) номер группы до «остановки» введен Для каждого указанного номера группы мы должны напечатать имена людей в группе. Я также добавлю пример проверки ошибок.
loop do
grp = loop do
print "Gimme a group number: "
grp = gets.chomp
break grp if (1..nbr_groups).cover?(grp.to_i) ||
grp.downcase == "stop"
puts "That's not a valid group number. Try again."
end
break if grp.downcase == "stop"
off = grp.to_i - 1
puts "The members of group #{grp} are #{arr[off].join(', ')}"
end
Если это запустить, и откликами будут "1\n"
, "99\n"
, "cat\n"
, "3\n"
и "stop"
, диалоговое окно будет выглядеть следующим образом:
Gimme a group number: 1
The members of group 1 are Ruth, Lou, Tim
Gimme a group number: 99
That's not a valid group number. Try again.
Gimme a group number: cat
That's not a valid group number. Try again.
Gimme a group number: 3
The members of group 3 are Bob, Bif
Gimme a group number: stop