我刚写了这段代码,但我对此并不满意。
data = {}
options.each{ |k,v| data.merge!({k.to_s => v}) }
基本上我有:
{:a => "something", :b => "something else", :c => "blah"}
......我想......
{"a" => "something", "b" => "something else", "c" => "blah"}
...为了将它发送到由于某种原因不处理符号的gem。在我编写的代码中,选项是原始哈希,数据是更新的,但如果我只能使用1个变量,那就更好了。
你们如何重构我的代码?
答案 0 :(得分:6)
data = Hash[options.map{ |k,v| [k.to_s,v] }]
对于足够有趣的哈希值,答案之间没有显着差异
require 'benchmark'
options = Hash[('aaaa'..'zzzz').map{|i| [i.to_sym,i]}]
Benchmark.bm(100) do |x|
x.report("map") {Hash[options.map{ |k,v| [k.to_s,v] }] }
x.report("zip") {Hash[options.keys.map(&:to_s).zip(options.values)]}
x.report("inject") {options.inject({}) { |h, (k, v)| h[k.to_s] = v; h }}
end
user system total real
map 3.490000 0.090000 3.580000 ( 4.049015)
zip 3.780000 0.020000 3.800000 ( 3.925876)
inject 3.710000 0.110000 3.820000 ( 4.289286)
答案 1 :(得分:3)
注入似乎赢了:
require 'benchmark'
a = {:a => "something", :b => "something else", :c => "blah"}
Benchmark.bm(10000) do |x|
x.report("map") {Hash[a.map{ |k,v| [k.to_s,v] }] }
x.report("zip") {Hash[a.keys.map(&:to_s).zip(a.values)]}
x.report("inject") {a.inject({}) { |h, (k, v)| h[k.to_s] = v; h }}
end
给出
user system total real
map 0.000000 0.000000 0.000000 ( 0.000033)
zip 0.000000 0.000000 0.000000 ( 0.000018)
inject 0.000000 0.000000 0.000000 ( 0.000014)
答案 2 :(得分:1)
答案 3 :(得分:1)
Rails为Hash添加了stringify_keys
方法。如果你不使用Rails,你可以简单地从ActiveSupport复制代码(开源ftw!):
def stringify_keys
inject({}) do |options, (key, value)|
options[key.to_s] = value
options
end
end
答案 4 :(得分:0)
借助activesupport gem,您可以创建一个新哈希(或转换现有哈希),其中字符串和哈希键可以互换。
#!/usr/bin/ruby1.8
require 'active_support'
h = HashWithIndifferentAccess.new({'a'=>1, :b=>2})
p h[:a] => 1
p h['a'] => 1
p h[:b] => 2
p h['b'] => 2