2016-02-13 149 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"