如何重构此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到另一个版本发生显著变化,因此今天更快的可能不会是明年。你应该用更多的迭代次数来进行基准测试,这些计时看起来太接近零而不相关。你应该用更多的迭代次数来进行基准测试,这些计时看起来太接近零而不相关。