Ruby 多个选项的字符串替换

Ruby string substitution with multiple options

我想进行字符串替换。使用 gsubtr 我可以提供单个输入字符并将其映射到单个输出值,但我想基于多个映射创建多个输出字符串:

swap = { 
  'a' => ['$', '%', '^'],
  'b' => ['3'],
  'c' => ['4', '@'],
}

对于输入字符串 'abc',我应该得到以下输出字符串:

对于任意数量的输入和映射,是否有一种简单的方法可以做到这一点?实际上它可能是大约 10 个输入和最多 3 个映射,通常只有一个。

def gen_products(swap, str)
  swap_all = Hash.new { |_,k| [k] }.merge(swap) 
  arr = swap_all.values_at(*str.chars)
  arr.shift.product(*arr).map(&:join)
end

参见 Hash::new (with a block), Hash#values_at and Array#product。如果h = Hash.new { |_,k| [k] }h没有keyk,h[k]returns[k].

swap = { 'a'=>['$', '%', '^'], 'b'=>['3'], 'c'=>['4', '@'] }

gen_products(swap, "abc")
  #=> ["", "@", "%34", "%3@", "^34", "^3@"]

这里

swap_all = Hash.new { |_,k| [k] }.merge(swap) 
  #=> {"a"=>["$", "%", "^"], "b"=>["3"], "c"=>["4", "@"]}
vals = swap_all.values_at(*str.chars)
  #=> [["$", "%", "^"], ["3"], ["4", "@"]]

另一个例子:

gen_products(swap, "bca")
  #=> ["34$", "34%", "34^", "3@$", "3@%", "3@^"]

还有一个:

gen_products(swap, "axbycx")
  #=> ["$x3y4x", "$x3y@x", "%x3y4x", "%x3y@x", "^x3y4x", "^x3y@x"]

这里

swap_all = Hash.new { |_,k| [k] }.merge(swap)
  #=> {"a"=>["$", "%", "^"], "b"=>["3"], "c"=>["4", "@"]}
vals = swap_all.values_at(*str.chars)
  #=> [["$", "%", "^"], ["x"], ["3"], ["y"], ["4", "@"], ["x"]]