Как перевести несколько слов одновременно в Ruby?

#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 выражением.