Ruby 将字符串转换为哈希

Ruby 将字符串转换为哈希,ruby,hash,Ruby,Hash,我想知道是否有更好的方法将字符串转换为哈希。 我的字符串在结构上看起来总是完全一样的。 以下是一个例子: 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", :t

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

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"}
这就是它应该做的,我对此没有任何问题。 但是它非常不可读,我希望我的代码有一些重构选项

可以处理数组的数组:

@settings = Hash[
  string.split("\n")
  .map { |s| s = s.split(":"); [s[0].to_sym, s[1]] }
]
可以处理数组的数组:

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

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

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#symbol_keys

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

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

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#symbol_keys

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

如果在值之前有空格:

string = "range: 12\ntype: default\n"
此字符串应该是正确的YAML,因此您可以使用Ruby
YAML
library对其进行解析:

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

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

如果在值之前有空格:

string = "range: 12\ntype: default\n"
此字符串应该是正确的YAML,因此您可以使用Ruby
YAML
library对其进行解析:

require 'yaml'
string = "range: 12\ntype: default\n"
@settings = YAML.load(string)
# => {"range"=>12, "type"=>"default"}
所以我建议修改一下你的设置格式,如果你能做到的话

这将起作用:

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"}
这将有助于:

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"}

为什么不在值之前添加空格并使其成为YAML?为什么不在值之前添加空格并使其成为YAML?在所有答案中,这是解决在文本文件中存储键值对这一更大问题的最可靠的方法。我认为以这种方式看问题的背后,会使一个好答案和一个好答案之间产生差异+1这真的很好,但我不能使用Yamlo来回答所有问题,这是解决在文本文件中存储键值对这一更大问题的最可靠的方法。我认为以这种方式看问题的背后,会使一个好答案和一个好答案之间产生差异+1这真的很好,但我不能用yaml