2016-02-13 85 views
-1

我正在尝试编写一个方法,它接受一个字符串和一个散列,并根据散列键和值“编码”字符串。基于散列值转换字符串

def encode(str,encoding) 
end 

str = "12#3" 
encoding = {"1" => "one", "2"=> "two", "3"=> "three"} 

我期待的输出为"one two three"不在哈希键被替换为空字符串在字符串中的任何字符。

现在我的代码如下所示:

def encode(str, encoding) 
    output = "" 
    str.each_char do |ch| 
    if encoding.has_key?(ch) 
     output += encoding[ch] 
    else 
     output += "" 
    end 
    end 
    return output 
end 

任何帮助表示赞赏

+0

WOW ....从来没有这个作品...我有一个错字我的代码 –

回答

0

尝试:

def encode(str, encoding) 
    output = "" 
    str.each_char do |ch| 
    if encoding.has_key?(ch) 
     output += encoding[ch] + " " 
    else 
     output += "" 
    end 
    end 
    return output.split.join(' ') 
end 

str = "12#3" 
encoding = {"1" => "one", "2"=> "two", "3"=> "three"} 

p encode(str, encoding) #=> "one two three" 
+1

在迭代某个对象并将对象附加到对象之前初始化一个对象('output')通常是Ruby中的代码异味,表示有机会使用'map','reduce'或each_with_object等。 'str.each_char.with_object([]){| c,arr | arr << encoding [c] if encoding [c]} .join('')' –

+1

@Jordan我明白了,非常感谢小费。 –

+1

Zack,@Jordan提到“代码味道”。如果你不熟悉这个表达方式,那么就考虑“搁浅的鲸胴体”,例如,从来没有,例如 “新鲜出炉的面包”。 –

0

如果你期待“一二三”你只需要添加一个空格到您的concat行并返回之前,添加.lstrip以删除第一个空格。

提示:您不需要连接空字符串的“else”。如果“#”与编码散列不匹配,它将被忽略。

像这样:

#str = "12#3" 
#encoding = {"1" => "one", "2"=> "two", "3"=> "three"} 

def encode(str, encoding) 
    output = "" 
    str.each_char do |ch| 
    if encoding.has_key?(ch) 
     output += " " + encoding[ch] 
    end 
    end 
    return output.lstrip 
end 

# Output: "one two three" 
2

您可以使用使用String#gsub使用换人散列的形式,和一个简单的正则表达式:

str = "12#3" 
encoding = {"1"=>"one", "2"=>"two", "3"=>"three"} 

首先创建一个新的哈希值,增加了一个空间到每个值在encoding

adj_encoding = encoding.each_with_object({}) { |(k,v),h| h[k] = "#{v} " } 
    #=> {"1"=>"one ", "2"=>"two ", "3"=>"three "} 

现在执行替换和剥离多余的空间,如果的encoding的关键之一是str最后一个字符:

str.gsub(/./, adj_encoding).rstrip 
    #=> "one two three" 

又如:

"1ab 2xx4cat".gsub(/./, adj_encoding).rstrip 
    #=> "one two" 

红宝石判断的str每个字符( /./部分)等于adj_encodeing的密钥。如果是这样,她会将该键的值替换为该角色的值;否则她会用空字符串('')替换该字符。

0

我会做:

encoding = {"1" => "one", "2"=> "two", "3"=> "three"} 
str = "12#3" 
str.chars.map{|x|encoding.fetch(x,nil)}.compact.join(' ') 

或两行是这样的:

in_encoding_hash = -> x { encoding.has_key? x } 
str.chars.grep(in_encoding_hash){|x|encoding[x]}.join(' ') 
1

您可以通过Regexp.union建立符合你的钥匙正则表达式:

re = Regexp.union(encoding.keys) 
#=> /1|2|3/ 

scan的用于使用该正则表达式的键出现的字符串:

keys = str.scan(re) 
#=> ["1", "2", "3"] 

取使用values_at对应的值:

values = encoding.values_at(*keys) 
#=> ["one", "two", "three"] 

join用一个空格阵列:

values.join(' ') 
#=> "one two three" 

作为 “单行”:

encoding.values_at(*str.scan(Regexp.union(encoding.keys))).join(' ') 
#=> "one two three"