Weird observation here:
2.0.0-p353 :016 > "1,056".gsub!(/,/,'').to_i
=> 1056
2.0.0-p353 :017 > "955".gsub!(/,/,'').to_i
=> 0
Is there a way to consistently do this without breaking numbers that do not field a , in them?
I assumed the requirement was:
One way to do that is as follows:
str = "955"
str.tap { |s| s.delete!(',') }.to_i
#=> 955
str
#=> "955"
str = "1,955"
str.tap { |s| s.delete!(',') }.to_i
#=> 1955
str
#=> "1955"
str = "1,955,658"
str.tap { |s| s.delete!(',') }.to_i
#=> 1955658
str
#=> "1955658"
split(',').join. Instead use delete(',').to_i. It's over 2x times faster.split(',').join is neither fish nor foul: it doesn't mutate the receiver and it's inferior to delete if the receiver is not to be mutated. I'll revert to my original answer, slightly improved.Sigh... benchmarks people...
require 'fruity'
NUM = '1,234,567,890'
compare do
_delete { NUM.delete(',').to_i }
_gsub { NUM.gsub(',', '').to_i }
_scan {NUM.scan(/\d+/).join.to_i }
_split { NUM.split(',').join.to_i }
end
# >> Running each test 4096 times. Test will take about 1 second.
# >> _delete is faster than _split by 2.4x ± 0.1
# >> _split is faster than _gsub by 10.000000000000009% ± 1.0%
# >> _gsub is faster than _scan by 2.2x ± 0.1
In other words, use delete(',') to remove the delimiting commas and then convert the resulting string to an integer. Don't split it into an array and then rejoin it, don't scan it into an array, and don't let gsub convert ',' into a regex and then replace all matches with ''.
gsub!, like many other bang methods, returnsnilif no change is made."955".gsub(/,/,'').to_i(no exclamation mark) works fine, that's Cary's point