我有一个字符串需要转换成散列。字符串的键总是一个符号,值总是一个整数:
"a=1, b=2, c=3, d=4"
此字符串应返回如下所示的散列:
{ :a => 1, :b => 2, :c => 3, :d => 4 }
我尝试了几种不同的方法,但到目前为止我能做到的最接近的方法是将字符串拆分两次,第一次是逗号和空格,第二次是等号,然后创建符号:
def str_to_hash(str)
array = str.split(', ').map{|str| str.split('=').map{|k, v| [k.to_sym, v] }}
end
我期望得到以下输出:
{:a=>1, :b=>2, :c=>3, :d=>4}
相反,我得到了:
[[[:a, nil], [:"1", nil]], [[:b, nil], [:"2", nil]], [[:c, nil], [:"3", nil]], [[:d, nil], [:"4", nil]]]
如您所见,它创建了 8 个带有 4 个符号的独立字符串。我不知道如何让 Ruby 识别数字并将它们设置为键/值对中的值。我在网上查过,甚至向我的同事求助过,但到目前为止还没有找到答案。有人可以帮忙吗?
最佳答案
试试这个,我觉得它看起来更干净一些
s= "a=1, b=2, c=3, d=4"
Hash[s.scan(/(\w)=(\d)/).map{|a,b| [a.to_sym,b.to_i]}]
内部结构
#utilize scan with capture groups to produce a multidimensional Array
s.scan(/(\w)=(\d)/)
#=> [["a", "1"], ["b", "2"], ["c", "3"], ["d", "4"]]
#pass the inner Arrays to #map an replace the first item with a sym and the second to Integer
.map{|a,b| [a.to_sym,b.to_i]}
#=> [[:a, 1], [:b, 2], [:c, 3], [:d, 4]]
#Wrap the whole thing in Hash::[] syntax to convert
Hash[s.scan(/(\w)=(\d)/).map{|a,b| [a.to_sym,b.to_i]}]
#=> {:a=>1, :b=>2, :c=>3, :d=>4}
如果你想避免 Hash::[]
方法,我一直认为它很丑陋,你可以执行以下操作
#Ruby >= 2.1 you can use Array#to_h
s.scan(/(\w)=(\d)/).map{|a,b| [a.to_sym,b.to_i]}.to_h
#=> {:a=>1, :b=>2, :c=>3, :d=>4}
#Ruby < 2.1 you can use Enumerable#each_with_object
s.scan(/(\w)=(\d)/).each_with_object({}){|(k,v),obj| obj[k.to_sym] = v.to_i}
#=> {:a=>1, :b=>2, :c=>3, :d=>4}
虽然有很多其他方法可以解决这个问题,但这里的许多其他答案显然只是为了好玩。
Hash[*s.scan(/(\w)=(\d)/).flatten.each_with_index.map{|k,i| i.even? ? k.to_sym : k.to_i}]
关于ruby - 将字符串值转换为哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27296140/