2017-07-29 11 views
1

文字列置換を行いたい。 gsubまたはtrで、私は単一の入力文字を与えることができ、単一の出力値にマップするが、私は複数のマッピングに基づいて複数の出力文字列を作成したい:複数のオプションを指定したRuby文字列置換

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

入力文字列'abc'のために、私は次の出力を取得する必要があります文字列:

入力とマッピングの任意の数のためにこれを行う簡単な方法はありますか?実際には、入力は約10回、最大で3回ですが、通常は1回だけです。

+0

3つのネストされたループ(すべての組み合わせを列挙する)とtr/gsubと呼ばれる最も内側のループでは、これは簡単です(この場合)。 –

+0

一般的な実装を行うことは、少なくとも、些細なことではありませんが、私は認めます。しかし、それを試してみてください。 –

+0

ロビン、私の答えを選んでいただきありがとうございますが、あなたは本当にgreenieを与える前に(おそらく2時間以上)待つべきです。迅速な選択は他の回答を妨げる可能性があり、まだ答えに取り組んでいる他の人には迷惑です。急いではありません。チェックマークを外して後で決定することを検討してください。 –

答えて

6
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#values_atArray#product、(ブロックで)Hash::newを参照してください。 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]^"] 

と1以上:ここ

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

メソッドの2行目を 'first.product(* others)'に短縮するために、 'first、* others = swap.values_at(* str.chars)'を使って代入中に配列を分解することができます – Stefan

+0

良いアイデア、 @シュテファン。私はかなり正しいことがあることを知っていた。私はそれを変更します。ありがとう。 –

関連する問題