将String转换为Hash

时间:2014-09-08 10:12:04

标签: ruby hash

我想知道是否有更好的方法将字符串转换为哈希。 我的String在结构上总是看起来完全一样。 这是一个例子:

string = "range:12\ntype:default\n"

@settings = Hash[
  *string.downcase
  .split("\n")
  .map{|s| [s.split(":")[0].to_sym, s.split(":")[1]]}
  .flatten
]

p @settings
# => {:range=>"12", :type=>"default"}

这可以做它应该做的事情,我对此没有任何问题。 但它非常难以理解,我希望我的代码有一些重构选项。

5 个答案:

答案 0 :(得分:5)

Hash[*string.split(/[:\n]/)]
# => {"range"=>"12", "type"=>"default"} 

答案 1 :(得分:4)

您可以使用String.scan搜索字符串中的键值对,然后通过调用to_h将生成的数组数组转换为哈希值:

string.scan(/(.+):(.+)\n/).to_h
#=> {"range"=>"12", "type"=>"default"}

如果您确实需要符号键,则可以在转换为哈希值之前使用Array#map

string.scan(/(.+):(.+)\n/).map {|k,v| [k.to_sym, v]}.to_h
#=> {:range=>"12", :type=>"default"}

如果您正在使用Rails,那么已经有了内置方法Hash#symbolize_keys

string.scan(/(.+):(.+)\n/).to_h.symbolize_keys
#=> {:range=>"12", :type=>"default"}

答案 2 :(得分:2)

如果您的值之前有空格:

string = "range: 12\ntype: default\n"

这个字符串是正确的YAML,所以你可以用Ruby yaml库解析它:

require 'yaml'
string = "range: 12\ntype: default\n"
@settings = YAML.load(string)
# => {"range"=>12, "type"=>"default"}

所以我建议稍微修改你的设置格式,如果你能做到的话。

答案 3 :(得分:2)

这样可行:

string = "range:12\ntype:default\n"

string.split("\n").each_with_object({}) { |s, h|
  k, v = s.split(':')
  h[k.to_sym] = v
}
#=> {:range=>"12", :type=>"default"}

答案 4 :(得分:1)

Hash::[]可以处理数组:

@settings = Hash[
  string.split("\n")
  .map { |s| s = s.split(":"); [s[0].to_sym, s[1]] }
]