返回哈希作为 'else branch' 取决于正则表达式匹配

Returning a Hash as an 'else branch' dependant on Regex match

以下是一项挑战任务,因此可能无法反映 'real-world' 代码。我正在尝试以一种将一个散列的属性用于 return 新散列的方式来设置我的方法。在这种情况下,我的方法是将电子邮件作为 字符串 ,使用正则表达式推断电子邮件的顶级域名,然后根据顶级域名输出基于哈希的消息。在此示例中,它以其注册的顶级域名的语言生成电子邮件。

该代码可以正常工作,但未通过一项测试: "应该 return 一个包含任何其他 ccTlD 邮件的英文消息信息的哈希值"

当顶级域名不在原始翻译哈希中时,我不知道如何设置默认值 'en',即 bob@gmail.pl 应该 return 英文基于翻译。

奖励:我还注意到我的 Rubocop 不喜欢我的样式,因为我的 compose_translated_email 方法有太多行。我不知道如何在不使 that 方法太长的情况下将翻译放入另一种方法中。

任何帮助将不胜感激 - 而不仅仅是答案,如果您也能解释代码的作用,我将不胜感激。谢谢。

LOCALES = {
  en: {
    subject: "Our website is online",
    body: "Come and visit us!",
    closing: "See you soon",
    signature: "The Team"
  },
  fr: {
    subject: "Notre site est en ligne",
    body: "Venez nous rendre visite !",
    closing: "A bientot",
    signature: "L'équipe"
  },
  de: {
    subject: "Unsere Website ist jetzt online",
    body: "Komm und besuche uns!",
    closing: "Bis bald",
    signature: "Das Team"
  }
}

def compose_translated_email(email)
  username = email.match(/^(\w*)/)[1]
  domain = email.match(/[^@]+(?=\.)/)[0]
  tld = email.match(/.*\.(\w+)$/)[1]

  tldsym = tld.to_sym

  new_hash = {
    username: username,
    domain: domain,
    tld: tld,
    subject: LOCALES[tldsym][:subject],
    body: LOCALES[tldsym][:body],
    closing: LOCALES[tldsym][:closing],
    signature: LOCALES[tldsym][:signature]
  }
  return new_hash
end

在创建哈希之前将 tld 的值默认为 en 是否足够?如:

(...)
# default to english language
tldsym = tld.to_sym
# i.e. if the key does not exist in LOCALES, use "en" as key
tldsym = LOCALES.key?(tldsym) ? tldsym : "en".to_sym
(...)

考虑到您的奖励问题,您可以通过循环填充翻译后的值以节省几行:

(...)
new_hash = {
  username: username,
  domain: domain,
  tld: tld,
}
%i(subject body closing signature).each { |k| new_hash[k] = LOCALES[tldsym][k] }
(...)

解释: 我们正在迭代一个键名数组(主题、正文、结尾、签名),这些键名将从 LOCALES 散列中填充。 %i 符号(需要 Ruby 2.0.0 或更高版本)立即为我们提供了一个包含这些键符号的数组,因此 each 块内不需要 to_sym -我们可以在源哈希和目标哈希中都使用当前符号(在本例中命名为 k)。


通过迭代填充其他哈希槽来节省额外的行:

(...)
new_hash = {}
%W(username domain tld).each { |k| new_hash[k.to_sym] = eval(k) }
%i(subject body closing signature).each { |k| new_hash[k] = LOCALES[tldsym][k] }
(...)

解释:这里我们使用%W来获取字符串数组,所以我们需要to_sym作为目标中的键。然后使用 evaluation 解析目标值,我猜这可能不是最干净的样式。

请原谅任何愚蠢的错误,我自己也是 Ruby 初学者 :)

我会这样做:

LOCALES = Hash.new({
  subject: "Our website is online",
  body: "Come and visit us!",
  closing: "See you soon",
  signature: "The Team"
}).merge({
  'fr' => {
    subject: "Notre site est en ligne",
    body: "Venez nous rendre visite !",
    closing: "A bientot",
    signature: "L'équipe"
  },
  'de' => {
    subject: "Unsere Website ist jetzt online",
    body: "Komm und besuche uns!",
    closing: "Bis bald",
    signature: "Das Team"
  }
}).freeze

def compose_translated_email(email)
  email.scan(/([^@]+)@(.*\.([^.]+))/) => [[username, domain, tld]]

  {
    username:,
    domain:,
    tld:,
    **LOCALES[tld]
  }
end

这不是世界上最漂亮的代码,但它会做到。