2016-10-05 10 views
2

このフォーマットの任意の文字列をa = "a=2, b=3, c=4, d=5"のシンボル(キー)と整数(値)のハッシュに変換したいと思います。Rubyで文字列をハッシュ記号と整数に変換する

この場合、予想入力は{:a=>2, :b=>3, :c=>4, :d=>5}です。

これは私が持っているものです。

def hash_it(str) 
    str.split(", ").map{|s| s.split("=")}.to_h 
end 

hash_it(str)戻り{"a"=>"2", "b"=>"3", "c"=>"4", "d"=>"5"}。閉じるが、それほどではない。私は、キーをシンボルと値に整数に変換する方法がわかりません。私はそれらを別々に変換することができます:

str.split(", ").map{|s| s.split("=")}.map{|n| n[0].to_sym} 
#=> [:a, :b, :c, :d] 
str.split(", ").map{|s| s.split("=")}.map{|n| n[1].to_i} 
#=> [2, 3, 4, 5] 

しかし私は意図した目的のために一緒に置くことはできません。

"a=2, b=3, c=4, d=5"の形式の任意の文字列をシンボル間キー値のハッシュに変換するにはどうすればよいですか?{:a=>2, :b=>3, :c=>4, :d=>5}

+0

それは 'A'があなたの配列、' evalの「{#{a.gsub(/ \ W + /、 ':\ 1')であれば、ことは注目におそらく価値があります}} "#=> {:a => 2、:b => 3、:c => 4、:d => 5}' –

答えて

7

私はおそらくそれをこのようにします:

str = "a=2, b=3, c=4, d=5" 
str.scan(/(\w+)=(\d+)/).map {|k,v| [ k.to_sym, v.to_i ] }.to_h 

scanだけで、各キーと値のペアを抽出し、残りは自明であるべき。

+0

は、実際にはいくつかの正規表現がここでうまくいくと思っていました –

+0

'scan'は素晴らしいツールですが、あなたのデータは元来のものとみなします。入力内の迷惑メールは無視されます。これは、望ましい動作または実際の問題の可能性があります。ちょっと警告。確かに – tadman

+0

@ tadmanこれは、ここに掲載されているすべてのソリューションと、実際にOPが提供する情報が少ないため、私たちが思いつくことができるあらゆるソリューションに当てはまります。たとえば、私の解決策は '='の両側に予期しない空白があると失敗するかもしれません。 'split'を使った解決策は予期しない末尾や重複した区切り文字で失敗するかもしれません。 –

2

あなたはとても近かったです!以下は少しあなたの試みを拡張/修正します:

a = "a=2, b=3, c=4, d=5" 

def hash_it(str) 
    str.split(", ").map{|s| s.split("=")}.map{|n| [n[0].to_sym, n[1].to_i]}.to_h 
end 

hash_it(a) #=> {:a=>2, :b=>3, :c=>4, :d=>5} 
+0

これは1ライナーなので、 'syms ='部分は必要ありません。 – tadman

+0

@ tadmanありがとう、固定。 –

0

この

String.class_eval do 
    def hashing 
     self.split("#{oper1}").map{|s| [ s.split("#{oper2}")[0].strip.to_sym,s.split("#{oper2}")[1].to_i]}.to_h 
    end 
end 

は "YOUR STRING" を.hashingし、ユーザーにそれをしたい場合はしてみてください "=" 別のデフォルトなどとして場所はこちら

String.class_eval do 
    def hashing(oper1= ',', oper2= '=') 
    self.split(oper1.to_s).map{|s| [ s.split(oper2.to_s)[0].strip.to_sym,s.split(oper2.to_s)[1].to_i]}.to_h 
    end 
end 

"YOUR STRING ".hashing 
#or 
"ANOTHER SRTING".hashing("|", "!") # for another split operators. 

希望します。

+0

ここのブラインド 'レスキュー'ステートメントは本当に悪いフォームですが、エラーを抑制し、たくさんのヘルプを提供しません。そのコードが生成することを期待している例外は何ですか? – tadman

+1

「#{oper1}」とは何ですか?あなたは非文字列の引数を予期しようとしていますか?そうでない場合、これはまったく意味がないので、 'oper1'を使うだけです。もしそうなら、なぜ単に 'oper1.to_s'をしないのですか? –

+0

@tadman、私はちょうどレスキューを使用していた通知のおかげで。 – som4ik

0
def hashify(str) 
    str.strip.split(/\s*(?:=|,\s)\s*/).each_slice(2).map { |k,v| [k.to_sym, v.to_i] }.to_h 
end 

str = " a = 2, b=3 , c= 4, d =5 " 
hashify str 
    #=> {:a=>"2", :b=>"3", :c=>"4", :d=>"5"} 

split動作「に分割は、任意の周囲の空白とともに、署名またはスペースが続くコンマ等しい」、読み出します。

手順は次のとおりです。

s = str.strip 
    #=> "a = 2, b=3 , c= 4, d =5" 
a = s.split(/\s*(?:=|,\s)\s*/) 
    #=> ["a", "2", "b", "3", "c", "4", "d", "5"] 
e = a.each_slice(2) 
    #=> #<Enumerator: ["a", "2", "b", "3", "c", "4", "d", "5"]:each_slice(2)> 

この列挙子が生成する値は、配列に変換することでわかります。

e.to_a 
    #=> [["a", "2"], ["b", "3"], ["c", "4"], ["d", "5"]] 

継続、

f = e.map { |k,v| [k.to_sym, v.to_i] } 
    #=> [[:a, 2], [:b, 3], [:c, 4], [:d, 5]] 
f.to_h 
    #=> {:a=>2, :b=>3, :c=>4, :d=>5} 
+0

OPは、ハッシュの値が数字であることを望んでいると思います。 –

+0

ありがとう、@ sagarpandya82。修正されます。 –

関連する問題