-2

「Hello world! :-)」のような単純な文字列入力を解析し、単語を分割していくつかの変更を行う配列に変換します。私は動作している次のコードを作成しましたが、Ruby の慣用句ではないようです。どうすれば改善できますか?

$mapping = Hash[
  "X" => "CODE_X",
  "Y" => "CODE_Y",
  "Z" => "CODE_Z",
]

def translate(input)
  result = []
  tmp = ""
  input.each_char do |c|
    if $mapping.has_key?(c)
      if result != ""
        result << "normal " + tmp
        tmp = ""
      end
      result << "special " + $mapping[c]
    else
      tmp += c
    end
  end
  if tmp != ""
    result << "normal " + tmp
  end
  return result
end

不必要な行が多くて読みにくいようです。それは何をしますか、おそらく例が役立ちます:

translate("HelloXworldYZ") =>
["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "special CODE_Z"]

または英語で:文字列を文字ごとに解析し、文字を再度連結します。(1) 文字がなくなるまで、または (2) 特殊文字 (マッピング) が存在するまで、結果の配列にそれらを「通常の」 + 文字列として追加し、文字列を配列に追加し、特殊文字を「特別な」として追加します。 + マッピングして、文字列の残りの部分を続行します。

4

3 に答える 3

2

どうですか

$mapping = { 'X' => 'CODE_X', 'Y' => 'CODE_Y', 'Z' => 'CODE_Z' }

def translate(input)
  input.
    split(/([#{$mapping.keys.map(&Regexp.method(:escape)).join}])/).
    each_slice(2).
    map {|normal, special| [unless normal.empty? then "normal #{normal}" end, "special #{$mapping[special]}"] }.
    map(&:compact).
    flatten
end

translate("HelloXworldYZ")
# => ["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "special CODE_Z"]

平易な英語の説明とテスト ケースが一致しないことに注意してください。平易な英語の説明から、結果は になるはずです["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "normal", "special CODE_Z"]。その場合、それはさらに簡単です:

$mapping = { 'X' => 'CODE_X', 'Y' => 'CODE_Y', 'Z' => 'CODE_Z' }

def translate(input)
  input.
    split(/([#{$mapping.keys.map(&Regexp.method(:escape)).join}])/).
    each_slice(2).
    map {|normal, special| [['normal', unless normal.empty? then normal end].compact.join(' '), "special #{$mapping[special]}"] }.
    flatten
end

translate("HelloXworldYZ")
# => ["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "normal", "special CODE_Z"]

しかし、strscanライブラリはより良い選択かもしれません。

于 2013-01-08T03:35:08.877 に答える
2
def translate(input,map)
  input.split(/([#{Regexp.escape map.keys.join}])/).map do |part|
    map.key?(part) ? "special #{map[part]}" : "normal #{part}" unless part.empty?
  end.compact
end

p translate( "HelloXworldYZ", 'X'=>'CODE_X', 'Y'=>'CODE_Y', 'Z'=>'CODE_Z' )
#=> ["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "special CODE_Z"]
于 2013-01-08T03:38:59.303 に答える
0
$mapping = Hash[
  "x" => "CODE_X",
  "y" => "CODE_Y",
  "z" => "CODE_Z",
]

def translate(input)
  $mapping.keys.each { |char| input.gsub!(char, "___#{char}___") } 
  array = input.split(/(___.___)/)
  result = []

  array.each do |word|
    if word.match /___.___/
      result << "special #{$mapping[word[3]]}"
    else
      result << "normal #{word}" unless word.empty?
    end
  end
  result
end

translate("Helloxworldyz")
#=> ["normal Hello", "special CODE_X", "normal world", "special CODE_Y", "special CODE_Z"]
于 2013-01-08T03:46:39.500 に答える