我正在解析简单的字符串输入,例如:" 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"]
或者用英语:按字符顺序解析字符串并再次连接字符。将它们添加到结果数组中&#34; normal&#34; + string直到(1)没有更多字符或(2)有一个特殊字符(mapping),它们将字符串添加到数组中并将特殊字符添加为&#34; special&#34; +映射并继续使用其余字符串。
答案 0 :(得分: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
库可能是更好的选择。
答案 1 :(得分: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"]
答案 2 :(得分: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"]