如何重构此Ruby代码以更改哈希值';将符号转换成字符串?

如何重构此Ruby代码以更改哈希值';将符号转换成字符串?,ruby,refactoring,Ruby,Refactoring,我刚写了这段代码,但我对此不太满意 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"} 。。。为了将它发送到一个由于某

我刚写了这段代码,但我对此不太满意

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。在我编写的代码中,options是原始散列,data是更新的散列,但是如果我只能使用1个变量,那就更好了

你们将如何重构我的代码

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)
对于一个足够有趣的散列,答案之间没有显著差异

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)

我建议这样做:

hsh = data.inject({}) { |h, (k, v)| h[k.to_s] = v; h }

(摘自)

我建议如下:

hsh = data.inject({}) { |h, (k, v)| h[k.to_s] = v; h }

(摘自)

Rails向散列添加了一个
stringify\u keys
方法。如果不使用Rails,只需从(开源ftw!)复制代码即可:


Rails向哈希添加了一个
stringify\u keys
方法。如果不使用Rails,只需从(开源ftw!)复制代码即可:

他似乎赢了:

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
给予

他似乎赢了:

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
给予


借助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

借助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

看起来好多了,谢谢!但是从数组创建这样的散列,这不是比我的解决方案慢吗?我知道除非您在大量数据上运行它,否则差异将是最小的,但我仍然有兴趣知道这一点。我想必须有人尝试各种备选方案才能看到相对性能。@Margg,相对性能还取决于您使用的哈希的大小。除非您知道哈希值总是很小,否则通常最好选择在存在显著差异时伸缩性更好的方法。否则,选择你认为更可读的。基准测试可以从一个版本或ruby到另一个版本发生重大变化,因此今天更快的可能不会是明年。这看起来更好,谢谢!但是从数组创建这样的散列,这不是比我的解决方案慢吗?我知道除非您在大量数据上运行它,否则差异将是最小的,但我仍然有兴趣知道这一点。我想必须有人尝试各种备选方案才能看到相对性能。@Margg,相对性能还取决于您使用的哈希的大小。除非您知道哈希值总是很小,否则通常最好选择在存在显著差异时伸缩性更好的方法。否则,选择你认为更可读的。基准可以从一个版本或ruby到另一个版本发生显著变化,因此今天更快的可能不会是明年。你应该用更多的迭代次数来进行基准测试,这些计时看起来太接近零而不相关。你应该用更多的迭代次数来进行基准测试,这些计时看起来太接近零而不相关。