Ruby: Как напечатать зеркальное письмо

#ruby #sorting #hash

Вопрос:

В хэше я хочу иметь возможность преобразовать A в печать Z, отражающую его букву.

 converter = {
  "A" => "Z",
  "B" => "Y",
  "C" => "X",
  "D" => "W"
}
 

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

1. В чем именно заключается ваш вопрос? Как преобразовать массив? Как построить отображение?

2. Что вы хотите, чтобы произошло с вводимыми данными, которые не являются прописными буквами ASCII? Итак, такие вещи, как '6' , 'é' , ' ' , или даже 'a' ?

3. извините @spickermann, я хотел поставить хэш, а не массив, извините за то, что вызвал путаницу

Ответ №1:

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

 MAPPING = Hash[("A".."Z").zip(("A".."Z").to_a.reverse)]

def mirror(letter)
  MAPPING.fetch(letter)
end
 

fetch вызовет исключение, если письмо не будет найдено (например mirror('a') )

или вы можете сделать некоторые вычисления с обычностью буквы. Это работает, потому что A-Z имеют ординарность 65-90 (без пробелов).

 def mirror(letter)
  a = "A".ord
  z = "Z".ord
  distance = z - letter.ord
  (a   distance).chr
end
 

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

1. Большое вам спасибо за вашу помощь. Ты потрясающая!!!

Ответ №2:

Еще Один Способ В Ruby:

 a=('A'..'Z').to_a
search_char = 'B'
result = a[-1-a.index(search_char)]
 

Гораздо более простой и быстрый способ с меньшим количеством ошибок-это транслитерация всей строки вместо работы по одному символу за раз:

 az = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
za = 'ZYXWVUTSRQPONMLKJIHGFEDCBA'
'Anywhere IT WORKS'.tr az,za      # => "Znywhere RG DLIPH"
 

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

1. za = az.reverse

2. Конечно. Я использовал константу для ясности и удобства сравнения во время тестирования.

3. Спасибо вам за вашу помощь! Этот код даже преобразует все слова. Еще раз спасибо.

Ответ №3:

Вот мой взгляд на это:

 def mirror str
  str.tr(('a'..'z').to_a.join, ('a'..'z').to_a.reverse.join)
     .tr(('A'..'Z').to_a.join, ('A'..'Z').to_a.reverse.join)
end

mirror "Meow" #=> "Nvld"

 

отредактируйте, чтобы не создавать массивы при каждом вызове:

 class Mirror
  LOWER = ('a'..'z').to_a.join.freeze
  UPPER = ('A'..'Z').to_a.join.freeze
  def self.mirror str
    str.tr(LOWER, LOWER.reverse)
       .tr(UPPER, UPPER.reverse)
  end
end

puts Mirror.mirror "Meow"
 

Или, если вы хотите пофантазировать и просто добавить зеркальный метод ко всем строкам:

 class String
  LOWER = ('a'..'z').to_a.join.freeze
  UPPER = ('A'..'Z').to_a.join.freeze
  def mirror
    self.tr(LOWER, LOWER.reverse)
        .tr(UPPER, UPPER.reverse)
  end
end

puts "Meow".mirror
 

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

1. Обратите внимание, что этот метод создает несколько объектов (4 диапазона, 4 массива, 4 строки) при каждом вызове. Может быть, переместить строки в константы?

2. Да, если это то, что называется » много «, то это абсолютно то, о чем стоит беспокоиться. Тем не менее, я пытался сделать его кратким (и не загрязняющим окружающую среду).

Ответ №4:

Вы также можете использовать методы String#ord и Integer#chr

 def mirror(l)
  (l.ord   (25 - ((l.ord - "A".ord) * 2))).chr
end
 

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

1. @muistooshort вы получаете a 'j' и an out of range error соответственно

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

3. @OscarRyz : Не будет работать, если строка закодирована в, т. е. EBCDIC .

4. @user1934428 Да, описание проблемы довольно расплывчатое. Вы правы насчет EBCDIC, я предполагаю, что это просто строковые литералы, которые в Ruby кодируются на US_ASCII до Ruby 2 и UTF-8 после, так что это все равно должно работать. В этом случае я думаю, что расширение карты, которая изначально была у OP, является лучшим решением.

5. @OscarRyz: В Ruby есть «множественная кодировка». Кодировка является частью каждого String экземпляра. Следовательно, вы можете смешивать кодировки в программе: если вы, например, читаете данные из базы данных мэйнфреймов и решите не преобразовывать кодировку во время чтения, в конечном итоге некоторые строковые переменные будут EBCDIC, а другие-UTF8.