#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'
и anout 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.