как изменить nil на » » в массиве

#ruby

#ruby

Вопрос:

 #ask user for string input
puts "Enter Text"
# text user has entered
text = "Test text"
#put text into a array - "split" by just words and spaces
words = text.downcase.split('')
#array of letters a to z in array 
a_z = ('a'..'z').to_a 

#idealy - take each letter in text string and match them to a_z's index from 0-25 
#space values in text are replaced in array with " " instead of nil

words.map { |x| a_z.index(x) }
  

Я пытаюсь взять текст, разделить текст, превратить текст в число на основе индекса от a до z… сдвиньте это число, рекомбинируйте и превратите обратно в текст…

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

как я могу заменить nil на » «, чтобы мой массив мог, например, выглядеть так:

 #=> [1,2," "]
  

вместо:

 #=> [1,2,nil]
  

Комментарии:

1. Ваши входные и выходные данные не совпадают. Также сбивает с толку то, что вызывается переменная, содержащая символы words .

2. Не уверен, чего именно вы пытаетесь достичь здесь, но вы также можете рассмотреть возможность использования split(" ") — т. е. Получить массив слов, а не массив букв. (Это кажется более подходящим, учитывая, что вы использовали имя переменной words !)

Ответ №1:

Код

 def shift_and_remove(str, shift)
  h = make_hash 'a'..'z', shift
  h.default_proc = ->(h,k) {' '}
  str.gsub(/./,h)
end

def make_hash(r, shift)
  base = r.first.ord
  r.each_with_object({}) { |c,h| h[c] = (base   (c.ord-base shift) % 26).chr }
end    
  

Примеры

 str = "Now is the time for 007 to appear!"
shift_and_remove(str, 0)  #=> " ow is the time for     to appear " 
shift_and_remove(str, 1)  #=> " px jt uif ujnf gps     up bqqfbs " 
shift_and_remove(str, 4)  #=> " sa mw xli xmqi jsv     xs ettiev " 
shift_and_remove(str, -1) #=> " nv hr sgd shld enq     sn zoodzq " 
shift_and_remove(str, -2) #=> " mu gq rfc rgkc dmp     rm ynncyp "
  

Обратите внимание, что во всех случаях «N» было преобразовано в пробел, «w» из «Now» было сдвинуто на «a» в третьем примере, а «a» из «appear» было сдвинуто на «z» и «y», соответственно, в последних двух примерах.

Объяснение

Когда shift #=> 2 хэш выглядит следующим образом:

 h[c] = ('a'.ord   (c.ord-'a'.ord shift) % 26).chr }
  #=> {"a"=>"c", "b"=>"d", "c"=>"e", "d"=>"f", "e"=>"g", "f"=>"h", "g"=>"i",
  #    "h"=>"j", "i"=>"k", "j"=>"l", "k"=>"m", "l"=>"n", "m"=>"o", "n"=>"p",
  #    "o"=>"q", "p"=>"r", "q"=>"s", "r"=>"t", "s"=>"u", "t"=>"v", "u"=>"w",
  #    "v"=>"x", "w"=>"y", "x"=>"z", "y"=>"a", "z"=>"b"} 
  

Все буквы от «a» до «x» сопоставляются со следующей буквой, тогда как «y» и «z» сопоставляются с «a» и «b» соответственно. Аналогично, когда shift #=> -1 «a» сопоставляется с «z», а все остальные буквы сопоставляются с предыдущей буквой.

При этом используется форма String#gsub, которая использует хэш для определения замены каждого символа в string ( /./ ) . Метод Hash#default_proc= создает proc, который выдает значение h[k] , когда в хэше h нет ключа k , а именно пробела.

Заглавные буквы

Если какие-либо присутствующие заглавные буквы должны быть заменены заглавными буквами (а не преобразованы в пробелы), требуется лишь небольшая модификация.

 def shift_and_remove(str, shift)
  h = make_hash('a'..'z', shift).merge make_hash('A'..'Z', shift)
  h.default_proc = ->(h,k) {' '}
  str.gsub(/./,h)
end

shift_and_remove(str, 0)  #=> "Now is the time for     to appear " 
shift_and_remove(str, 1)  #=> "Opx jt uif ujnf gps     up bqqfbs " 
shift_and_remove(str, 4)  #=> "Rsa mw xli xmqi jsv     xs ettiev " 
shift_and_remove(str, -1) #=> "Mnv hr sgd shld enq     sn zoodzq " 
shift_and_remove(str, -2) #=> "Lmu gq rfc rgkc dmp     rm ynncyp " 
  

Комментарии:

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

2. ОЛади, я рад, что ты нашел это полезным. Обратите внимание, что я только что внес несколько изменений.