Один из возможных вариантов - использование Range и отображение диапазона с использованием Enumerable # map .
Например, данные n = 3
спортсменов, базовый пример:
(1..n).map { |n| [n] } #=> [[1], [2], [3]]
Итак, добавив некоторые ваши спецификации в базовый пример:
n = 3
res = (1..n).map do |n|
r1 = rand(30..89)
r2 = rand(90..119)
r3 = rand(120..360)
score = r1 + r2 + r3
[n, r1, r2, r3, score]
end
#=> [[1, 38, 93, 318, 449], [2, 64, 93, 259, 416], [3, 83, 93, 343, 519]]
Альтернативный способ добавления суммы элементов в массив - использование
Object # tap:
[5,10,15].tap{ |a| a << a.sum } #=> [5, 10, 15, 30]
Таким образом, вы можете написать:
[rand(30..89), rand(90..119), rand(120..360)].tap{ |a| a << a.sum }
Это позволяет записать один вкладыш (используя Array # unshift ):
(1..n).map { |n| [rand(30..89), rand(90..119), rand(120..360)].tap{ |a| a << a.sum }.unshift n }
Исправление вашего кода Визуализация установки:
field = 3 # no user input for example
p athlete = Array.new(5) #=> [nil, nil, nil, nil, nil]
p triathalon = Array.new(field){athlete.dup} #=> [[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]
ПРИМЕЧАНИЕ athlete.dup
, чтобы избежать ссылкик тому же объекту.
Как только вы видите ваши объекты (athlete
и triathalon
), вы можете понять, что не требуется перебирать вложенный массив, просто доступ по индексу:
count=1
triathalon.each do |athlete|
athlete[0] = count
athlete[1] = rand(30..89)
athlete[2] = rand(90..119)
athlete[3] = rand(120..360)
athlete[4] = athlete[1] + athlete[2] + athlete[3]
count+=1
end
Улучшение: чтобы избавиться от счетчика используйте Enumerable # each_with_index .