#ruby #substitution
#ruby #подстановка
Вопрос:
Я пытаюсь создать переводчик подстановки для языка, который мы с моим другом создали. На этом языке определенные вещи должны происходить одновременно, и я не могу понять, как это сделать в Ruby.
С помощью простых вещей, таких как замена гласных, т. е.
a --> u
i --> o
o --> i
u --> a
Я только что сделал это:
input.tr("aiou", "uoia")
Но я не могу найти способ сделать так, чтобы следующие переводы выполнялись одновременно:
no --> e
e --> y
y --> el
чтобы фраза «yellow rhino» стала «elyllow rhie».
Любые предложения или примеры того, что я могу сделать ? gsub
? tr
? Совсем другой метод?
Комментарии:
1. Хотя это не самый прямой подход, вы действительно можете использовать String#tr здесь. Начиная с хэша @tadman
MAP
, можно было бы написатьg={"no"=>128.chr, "el"=>129.chr}; gi=g.invert; s1,s2 = MAP.to_a.transpose.map{ |a| a.map {|s| g.fetch(s, s)}.join}; "ienoay".tr(s1, s2).each_char.map {|s| gi.fetch(s, s)}.join #=> "oyniuel"
. Здесьs1 #=> "aiouex80y"; s2 #=> "uoiayex81"
. См. Hash#fetch , довольно полезный метод. Просто говорю.
Ответ №1:
Сначала вы определяете карту подстановки:
MAP = {
'a' => 'u',
'i' => 'o',
'o' => 'i',
'u' => 'a',
'y' => 'el',
'no' => 'e',
'e' => 'y'
}
Затем вы можете превратить это в регулярное выражение, чтобы сопоставить все «ключи» за один раз:
SUBST = Regexp.union(MAP.keys)
Это удобно, потому gsub
что можно использовать эти таблицы сопоставления для выполнения подстановки:
def translate(words)
words.gsub(SUBST, MAP)
end
Это означает, что вы можете сделать это:
puts translate("translate multiple words simultaneously")
# => trunsluty maltoply wirds somaltunyiaslel
tr
это отличный инструмент, но он ограничен заменами одного символа. gsub
может делать все tr
, что может, и даже больше.
Комментарии:
1. @kaolincash Переполнение стека Способ выразить свою благодарность — принять этот ответ (нажмите на галочку слева, чтобы она стала зеленой).
2. @matt Обычно у новых пользователей есть период ожидания, прежде чем они смогут его принять. Правила отличаются для <100 повторений.
3. @tadman Да, я не хочу говорить за вас, просто убедившись, что OP знает об этом, поскольку новые пользователи часто этого не делают. Кстати, потрясающий ответ; Я понятия не имел об этом. Возникает вопрос: «Как долго это продолжается»? 🙂
4. Просто нужно быть осторожным с тем, как вы строите «map» в этом случае, чтобы не получить преждевременные совпадения, например
{ "o" => "i", "oh" => "no"}
5. @engineersmnky это очень хороший момент. Совпадения должны либо не перекрываться по первой букве, либо упорядочиваться от самой длинной к самой короткой. Это можно было бы сделать с помощью прохода перед регулярным
sort_by
выражением.