3

In ruby,

"a".next [or] "a".succ # => "b"
"aa".next # => "ab"
"z".next # => "aa" # two a's after one z

How to it in Javascript? Something like:

incr_str("aaa") ===> aab
incr_str("zzz") ===> aaaa
1
  • 2
    Nothing built in, you'd have to make your own helper. Commented Aug 5, 2013 at 5:06

4 Answers 4

4

A google search for "Ruby string succ Javascript" returns this gist from Devon Govett called "An implementation of Ruby's string.succ method in JavaScript" which appears to be what you're after...

/*
 * An implementation of Ruby's string.succ method.
 * By Devon Govett
 *
 * Returns the successor to str. The successor is calculated by incrementing characters starting 
 * from the rightmost alphanumeric (or the rightmost character if there are no alphanumerics) in the
 * string. Incrementing a digit always results in another digit, and incrementing a letter results in
 * another letter of the same case.
 *
 * If the increment generates a carry, the character to the left of it is incremented. This 
 * process repeats until there is no carry, adding an additional character if necessary.
 *
 * succ("abcd")      == "abce"
 * succ("THX1138")   == "THX1139"
 * succ("<<koala>>") == "<<koalb>>"
 * succ("1999zzz")   == "2000aaa"
 * succ("ZZZ9999")   == "AAAA0000"
 */

function succ(input) {
  var alphabet = 'abcdefghijklmnopqrstuvwxyz',
    length = alphabet.length,
    result = input,
    i = input.length;

  while(i >= 0) {
    var last = input.charAt(--i),
        next = '',
        carry = false;

    if (isNaN(last)) {
        index = alphabet.indexOf(last.toLowerCase());

        if (index === -1) {
            next = last;
            carry = true;
        }
        else {
            var isUpperCase = last === last.toUpperCase();
            next = alphabet.charAt((index + 1) % length);
            if (isUpperCase) {
                next = next.toUpperCase();
            }

            carry = index + 1 >= length;
            if (carry && i === 0) {
                var added = isUpperCase ? 'A' : 'a';
                result = added + next + result.slice(1);
                break;
            }
        }
    }
    else {
        next = +last + 1;
        if(next > 9) {
            next = 0;
            carry = true
        }

        if (carry && i === 0) {
            result = '1' + next + result.slice(1);
            break;
        }
    }

    result = result.slice(0, i) + next + result.slice(i + 1);
    if (!carry) {
        break;
    }
  }
  return result;
}
Sign up to request clarification or add additional context in comments.

3 Comments

@JonathanLonowski Agreed on the lmgtfy, which is why I don't point there, but is linking to the specific keywords on google so they can read further also considered rude? I didn't think so. As for the "link only" point, yep, fair enough, I was on my phone and didn't get around to posting the entire content of the gist.
@JonathanLonowski And I will admit, I'm not as active on meta as I should be, and have been away for a while, only just getting back into answering.
A version of this function is also included in my "Slang" library for JS string manipulation as slang.successor: github.com/devongovett/slang
1

I found RubyJs library. Please check it.

http://rubyjs.org/

<script src="ruby.min.js"></script>
<script>
var str = R("aaa");
alert(str.next());
</script>

Comments

1

Write a JavaScript function to get the successor of a string.

Note: The successor is calculated by incrementing characters starting from the rightmost alphanumeric (or the rightmost character if there are no alphanumerics) in the string. Incrementing a digit always results in another digit, and incrementing a letter results in another letter of the same case. If the increment generates a carry, the character to the left of it is incremented. This process repeats until there is no carry, adding an additional character if necessary.

console.log(successor("abcd"));     // "abce"
console.log(successor("THX1138"));  // "THX1139"
console.log(successor("<>"));       // "<>"
console.log(successor("1999zzz"));  // "2000aaa"
console.log(successor("ZZZ9999"));  // "AAAA0000"

function successor(str) {
  if (str.charAt(str.length - 1).match(/[a-z]|[0-9]/i) === null)
    // if not digit or letter
    return str;
  var lastCharCode = str.charCodeAt(str.length - 1) + 1; // increment last character

  if (lastCharCode == 123 || lastCharCode == 91 || lastCharCode == 58) {
    var newStr = str.slice(0, str.length - 1);
    lastCharCode == 58 ? (lastCharCode -= 10) : (lastCharCode -= 26); // go back 26 if its Z or z, 10 if 0
    var lastChar = String.fromCharCode(lastCharCode);

    return newStr.length > 0
      ? successor(newStr) + lastChar
      : (lastChar == "0" ? "1" + lastChar : lastChar + lastChar);
  }
  // in case of first number is 9 : add 1 in first position
  return str.slice(0, str.length - 1) + String.fromCharCode(lastCharCode);
}

Comments

0

A combination of String.fromCharCode() and "".charCodeAt() should be rather straight-forward to implement.

var FIRST = 97,
    LAST = 122;

function next (string) {
  var lastChar = string[string.length - 1];

  string = string.substring(0, string.length - 1);

  if(lastChar.charCodeAt(0) >= LAST) {
    // make last char a and append a
    lastChar = String.fromCharCode(FIRST) + String.fromCharCode(FIRST);
  }
  else {
    // Increase last char
    lastChar = String.fromCharCode(lastChar.charCodeAt(0) + 1);
  }

  return string + lastChar;
}

Very quick-and-dirty and behaves a bit weird (zzz -> zzaa instead of zaaa or zzza, not sure what behavior is best) , but it shows how you could go about implementing it (and atm i don't have time to write a more refined answer).

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.