1

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?

6
  • 5
    gsub!, like many other bang methods, returns nil if no change is made. Commented Jun 9, 2015 at 22:11
  • 2
    Why would you want to mutate the string before converting it to an integer? Commented Jun 9, 2015 at 22:16
  • @CarySwoveland because "1,056".to_i doesn't work. Commented Jun 9, 2015 at 22:19
  • 3
    @randombits just "955".gsub(/,/,'').to_i (no exclamation mark) works fine, that's Cary's point Commented Jun 9, 2015 at 22:24
  • 1
    Thanks for the greenie, but you really should hold off awhile, so as to not discourage other answers (which could be quite interesting). Feel free to withdraw the checkmark if you like. Commented Jun 9, 2015 at 22:50

2 Answers 2

1

I assumed the requirement was:

  • the receiver is a string held by a variable (as there is no point in mutating the receiver if it's a string literal);
  • commas, if present, are to be removed from the receiver (i.e., the receiver is to be mutated); and
  • the receiver is to be converted to an integer and the integer returned.

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" 
Sign up to request clarification or add additional context in comments.

2 Comments

Don't use split(',').join. Instead use delete(',').to_i. It's over 2x times faster.
randombits, I agree with @theTinMan completely (but not because of the benchmark results). I suggest you move the checkmark to his answer. My initial answer mutated the string to remove commas and return the integer value. I thought that was what you specifically wanted. I played around with other methods and somehow half-forget the requirement to mutate the string. :-) 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.
1

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 ''.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.