Reputation: 2991
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
Upvotes: 3
Views: 1320
Reputation: 59
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);
}
Upvotes: 1
Reputation: 14953
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).
Upvotes: 0
Reputation: 114
I found RubyJs library. Please check it.
<script src="ruby.min.js"></script>
<script>
var str = R("aaa");
alert(str.next());
</script>
Upvotes: 1
Reputation: 45132
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;
}
Upvotes: 4