多个选项的Ruby字符串替换

问题描述:

我想做字符串替换。随着gsubtr我可以给单个输入字符并将其映射到一个单一的输出值,但我想基于多个映射创建多个输出字符串:多个选项的Ruby字符串替换

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

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

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

+0

这很简单(在这种情况下)有三个嵌套循环(枚举所有组合),并且在最内层的循环中调用tr/gsub。 –

+0

虽然做一个通用的实现至少是非平凡的,我承认。不过试试吧。 –

+0

罗宾,感谢您选择我的答案,但您在授予绿党之前确实应该等待一段时间(或许还有2个半小时)。快速选择可能会阻止其他答案,而对于仍然在寻求答案的其他人,imo是无礼的。没有急于。请考虑删除复选标记并稍后决定。 –

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(与块),Hash#values_atArray#product。如果h = Hash.new { |_,k| [k] }h没有密钥k,则h[k]返回[k]

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

gen_products(swap, "abc") 
    #=> ["$34", "[email protected]", "%34", "%[email protected]", "^34", "^[email protected]"] 

这里

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^", "[email protected]$", "[email protected]%", "[email protected]^"] 

和一种或多种:

gen_products(swap, "axbycx") 
    #=> ["$x3y4x", "[email protected]", "%x3y4x", "%[email protected]", "^x3y4x", "^[email protected]"] 

这里

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"]] 
+1

哦,这很聪明:)忘了'.product'。递归地重新实现它。这看起来不像性感。 –

+4

您可以在分配过程中通过'first,* others = swap.values_at(* str.chars)'分解数组,以便将方法的第二行缩短为first.product(* others)' – Stefan

+0

好主意, @Stefan。我知道有些事情不完全正确。我会改变它。谢谢。 –