is there a better why how can I refactor this code, making sure that values in a Hash
are typecasted to true/false
if their value is '1'
or '0'
while leaving unaltered the rest?
I'm using Ruby 2.0.0 if that matters, and I'd like to improve this code.
def transform
hsh = {}
preferences.each do |k, v|
v = case v
when '1'
true
when '0'
false
else
v
end
hsh[k.to_sym] = v
end
hsh
end
updated with benchmarks
All right, here's the performance test based on the replies so far:
class Test
HSH = {"xxx"=>"xxx-rrr", "yyy"=>"0", "rrr"=>"1", "nnn"=>"0", "kkk"=>"1", "iii"=>"1", "lll"=>"default", "mmm"=>"76", "www"=>"1"}
def self.transform_case
hsh = {}
HSH.each do |k, v|
v = case v
when '1'
true
when '0'
false
else
v
end
hsh[k.to_sym] = v
end
hsh
end
def self.transform_ternary
Hash[ HSH.map { |k, v| [k.to_sym, v == '1' ? true : v == '2' ? false : v ] } ]
end
def self.transform_fetch
special_values = {"1" => true, "0" => false}
Hash[HSH.map { |k, v| [k.to_sym, special_values.fetch(v, v)] }]
end
def self.transform_negation
Hash[ preferences.map {|k,v| [k.to_sym, !!v]} ]
end
end
Benchmark.bm(20) do|b|
b.report('case') do
1500.times { Test.transform_case }
end
b.report('ternary') do
1500.times { Test.transform_ternary }
end
b.report('fetch') do
1500.times { Test.transform_fetch }
end
b.report('negation') do
1500.times { Test.transform_negation }
end
end
user system total real
case 0.010000 0.000000 0.010000 ( 0.009282)
ternary 0.010000 0.000000 0.010000 ( 0.013794)
fetch 0.010000 0.000000 0.010000 ( 0.012804)
negation 0.010000 0.000000 0.010000 ( 0.010760)
It appears that my original implementation is faster. Or is the BM test wrong?
HSH
should be a lot longer for your benchmark to be representative (possible differences in big'O) 2) intransform_fetch
you create aspecial_values
hash every time the method is called, which is not necessary and hurts performance \$\endgroup\$