简体   繁体   中英

Ruby string substitution with multiple options

I want to do string substitution. With gsub or tr I can give a single input character and map it to a single output value but I want to create multiple output strings based on multiple mappings:

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

For input string 'abc' , I should get the following output strings:

  • '$34'
  • '$3@'
  • '%34'
  • '%3@'
  • '^34'
  • '^3@'

Is there an easy way to do this for an arbitrary number of inputs and mappings? In reality it is likely to be about 10 inputs and at most 3 mappings, usually only one.

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

See Hash::new (with a block), Hash#values_at and Array#product . If h = Hash.new { |_,k| [k] } h = Hash.new { |_,k| [k] } and h does not have a key k , h[k] returns [k] .

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

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

Here

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

Another example:

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

and one more:

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

Here

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM