Вставка переменных в массивы - PullRequest
0 голосов
/ 17 января 2019

Я хочу сгенерировать текст и вставить его в массив. Пожалуйста, помогите.

new_vrms = Array.new[3] {"placeholder"}
puts "How many registration marks do you require?"
        how_many = gets.chomp!()
        i = 0
        while i < how_many.to_i do
                prefix =('a'..'z').to_a.shuffle.first(2).join
                year = 68
                suffix =('a'..'z').to_a.shuffle.first(3).join
                aVRM = (prefix.to_s + year.to_s + suffix.to_s)
                aVRM = aVRM.upcase!
                puts ("#{aVRM} added to index #{i}")
                #new_vrms.insert(0, 1)  <-Array.rb:14:in `<main>': undefined method `insert' for nil:NilClass (NoMethodError)
                #new_vrms.push << @aVRM  <-Array.rb:15:in `<main>': undefined method `push' for nil:NilClass (NoMethodError)
                #new_vrms[i] = ("#{aVRM}")  <- Array.rb:16:in `<main>': undefined method `[]=' for nil:NilClass (NoMethodError)
                i += 1
        end         
        puts ("Succesfully generated "+ i.to_s + " registration marks")

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Это расширенный комментарий о коде OP в целом, так что, пожалуйста, не голосуйте против (голосование в порядке).

Вы начинаете с

new_vrms = Array.new[3] {"placeholder"}

@ Серхио определил вашу проблему здесь, но кроме этого нет необходимости инициализировать значение каждого элемента массива («заполнитель») или даже фиксировать размер массива. Действительно, вы, очевидно, хотите вернуть массив с how_many элементами, а how_many пока не известно. Поэтому вы должны просто создать пустой массив здесь:

new_vrms = Array.new(0)

, что совпадает с

new_vrms = Array.new

который чаще пишется

new_vrms = []

Далее вы спросите пользователя, сколько элементов должно быть в массиве:

how_many = gets.chomp!()

Если пользователь введет "3", gets вернет "3\n" и gets.chomp вернет "3". Обратите внимание, что нет необходимости завершать метод (здесь chomp) с (), когда у него нет аргументов. Кроме того, chomp! не является неправильным, но обычно используется немутирующая версия chomp. Вы хотите, чтобы how_many было целым числом, но не строкой (gets всегда возвращает строку). Поэтому вам необходимо преобразовать его в целое число:

how_many = gets.chomp.to_i

Если вы посмотрите на документ для String # to_i , вы увидите, что "123abc".to_i #=> 123, то есть "123\n".to_i #=> 123, что означает, что нам не нужно chomp при преобразовании строки в целое число:

how_any = gets.to_i

Теперь мы знаем, сколько раз мы хотим повторить цикл (how_many), поэтому вы захотите использовать итератор и блок вместо while цикла:

how_many.times do |i|
  ...<your code to add elements to new_vrms>
end
new_vrms  # return the computed value

См. Целое число # раз .

Вы повторяете код при расчете prefix и suffix, поэтому давайте сделаем это отдельным методом:

LETTERS = ('A'..'Z').to_a 
  #=> ["A", "B", "C",...,"X", "Y", "Z"] 

def random_3_letters
  LETTERS.sample(3).join
end

См. Array # sample , который обеспечивает более прямой способ вычисления случайных троек букв. (Кроме того, мы можем рисовать из массива заглавных букв, поэтому нам не нужно преобразовывать образцы в верхний регистр позже. 1 Я создал константу LETTERS, чтобы нам не нужно было создавать массив каждый раз, когда вызывается метод. Теперь мы можем записать блок.

YEAR = "68"
how_many.times do |i|
  prefix = random_3_letters
  suffix = random_3_letters
  aVRM = prefix + YEAR + SUFFIX
  puts "#{aVRM} added to index #{i}")
  new_vrms.push(aVRM) 
end
new_vrms

На самом деле нет никаких оснований для определения переменных prefix и suffix, поскольку мы можем упростить это следующим образом.

YEAR = "68"
how_many.times do |i| 
  aVRM = random_3_letters + YEAR + random_3_letters
  puts "#{aVRM} added to index #{i}")
  new_vrms.push(aVRM) 
end
new_vrms 

Если вы хотите напечатать значение каждого элемента aVRM, лучше всего делать это вне цикла - в более общем случае - вне метода, который вы оберните вокруг кода. Если оператор puts "#{aVRM} added to index #{i}") извлечен из блока, переменная блока i больше не используется, поэтому ее можно опустить:

YEAR = "68"

def doit
  new_vrms = []
  gets.to_i.times do 
    new_vrms << random_3_letters + YEAR + random_3_letters
  end
  new_vrms 
end

Обратите внимание, что я изменил Array # push на более часто используемый Array # << и заменил переменные <code>how_many и aVRS.

Опытный Rubyist может усилить это еще больше (хотя входные значения также будут проверены на достоверность в реальном коде):

LETTERS = ('A'..'Z').to_a 
YEAR = "68"

def doit
  gets.to_i.times.with_object([]) do |_,new_vrms|
    new_vrms << (random_3_letters + YEAR + random_3_letters)
  end
end

def random_3_letters
  LETTERS.sample(3).join
end

doit  # entering "4"
  #=> ["ZPI68LWY", "PQV68HLD", "IZG68JCH", "EAC68WLY"]

Обратите внимание, что с помощью Enumerator # with_object мы удаляем оператор new_vrms = [] и new_vrms в конце, последний, потому что with_object заставляет блок возвращать «объект», значение new_vrms.

1 Обратите внимание, что вы никогда не должны писать str = str.upcase!, потому что str.upcase! возвращает nil, если str уже обработан (и, следовательно, в str не вносятся изменения). Смотрите Строка # upcase! . Многие методы «взрыва» ...! возвращают nil, когда в получателя не вносятся изменения.

0 голосов
/ 17 января 2019

Ошибка в инициализации массива. То, что у вас есть (Array.new[3]), рассматривается рубином как

(Array.new)[3]

Вы хотите передать 3 в new в качестве аргумента.

Array.new(3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...