这看起来很简单但我无法弄清楚如何将哈希字符串转换为哈希。
当我做一个Answer.find_by_sql时,我得到一个像这样的字符串
deepthought = "\"answertolife\"=>\"42\""
但我无法弄清楚如何将其变成哈希。
我试过了:
pry(main)> Hash[deepthought]
ArgumentError: odd number of arguments for Hash
pry(main)> JSON.parse deepthought
JSON::ParserError: 757: unexpected token at '"answertolife"=>"42"'
pry(main)> deepthought.to_json
=> "\"\\\"answertolife\\\"=>\\\"42\\\"\""
我看到How do I convert a String object into a Hash object?,但我仍然无法理解。
答案 0 :(得分:1)
试试这个
eval("{ #{deepthought} }")
用大括号{}包装deepthought字符串,然后使用eval
答案 1 :(得分:1)
有点晚了,但是如果您需要转换多个条目,那么效果很好。
def hstore_to_hash(hstore)
values = {}
hstore.gsub(/"/, '').split(",").each do |hstore_entry|
each_element = hstore_entry.split("=>")
values[each_element[0]] = each_element[1]
end
values
end
答案 2 :(得分:0)
这似乎有效,但感觉很脏。
JSON.parse "{ #{deepthought} }".gsub('=>', ':')
答案 3 :(得分:0)
Rails4支持hstore开箱即用,所以我可能会按照Rails4的方式处理字符串。如果查看Rails4 PostgreSQL特定的转换代码,你会发现string_to_hstore
:
def string_to_hstore(string)
if string.nil?
nil
elsif String === string
Hash[string.scan(HstorePair).map { |k, v|
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
[k, v]
}]
else
string
end
end
在同一个文件中稍微低一点,您会找到HstorePair
:
HstorePair = begin
quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
/(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
end
存放在方便的地方(可能在lib/
中的某处)并通过string_to_hstore
发送hstore字符串以将其解压缩为Hashes。