5

How can I confidently increment a string number in Ruby? I understand I can call "1".next and produce "2" but this does not work for negative numbers.

"-3".next
=> "-4"

How can I call to increment both positive and negative string digits? I want to return value as String.

4
  • 2
    You could roundtrip through a number: x.to_i.next.to_s Commented Sep 9, 2020 at 13:48
  • 1
    It's not interpreted as a negative number. More like "chapter-3" Commented Sep 9, 2020 at 14:23
  • 4
    The really correct way to do this is to figure out why you have a "string number" and not a number in the first place, and fix that problem, instead of trying to work around it. Commented Sep 9, 2020 at 14:37
  • @Jörg, I expect the really correct approach is to back up one more step and avoid incrementing the string representations of numbers that are mixed in with other text. Maybe we're saying the same thing: change the design. Commented Sep 9, 2020 at 23:19

3 Answers 3

5

You can convert that string to integer, call #next and then convert it back to string

'-3'.to_i.next.to_s
Sign up to request clarification or add additional context in comments.

Comments

1

You could just do ("-3".to_i + 1).to_s but that does not account for float values (if you cared for that). You can call gsub with a block and match with regex to convert and increment. next does not work for negatives as it only evaluates the rightmost numeric and pays no attention to the minus character. The below matches for integers or floats and increments them based on the integer type:

INCREMENTAL = 1

def increment_str(str)
  str.gsub(/(-)?\d+(.\d+)?/) { |x| x.include?(".") ? x.to_f + INCREMENTAL : x.to_i + INCREMENTAL }
end

increment_str("-3") => "-2"
increment_str("3") => "4"
increment_str("-3.0") => "-2.0"
increment_str("3.0") => "4.0"

Comments

1

Your answer depends on whether the input is integer or float. In each case, cast it to the appropriate numeric type (to_i to to_f), increment by 1, and cast back to string. For example:

['-1.23', '-1', '0', '1', '1.23'].each do |str|
  int_str_plus_1 = (str.to_i + 1).to_s
  float_str_plus_1 = (str.to_f + 1).to_s
  puts [str, int_str_plus_1, float_str_plus_1].join("\t")
end

Prints:

-1.23  0  -0.22999999999999998
-1     0  0.0
0      1  1.0
1      2  2.0
1.23   2  2.23

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.