1
\$\begingroup\$

I'm writing a function to increase a string so, for example, "aac" becomes "aad" and "aaz" becomes "aba". The result is horribly inelegant, I can't get it simple enough and I feel I'm missing something. How to improve that code?

function inc_str(str){
 var str = str.split("").map(function(a){ return a.charCodeAt(0); });
 var n = 1;
 while (n<str.length){
 str[str.length-n]++;
 if (str[str.length-n] > "z".charCodeAt(0))
 str[str.length-n] = "a".charCodeAt(0),
 ++n;
 else
 break;
 };
 return str.map(function(a){ return String.fromCharCode(a); }).join("");
};

Extra points for a brief functional style solution! (Even if it needs to implement other functional functions such as zip or whatever.)

asked Feb 23, 2013 at 16:59
\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

A recursive approach is much more elegant in this case:

function inc_str(str) {
 var last = str[str.length - 1],
 head = str.substr(0, str.length - 1);
 if (last === "z") {
 return inc_str(head) + "a";
 } else {
 return head + String.fromCharCode(last.charCodeAt(0) + 1);
 }
}

Making it wrap around for inc_str('z') is left as an exercise for the reader (hint: last becomes undefined).

Joseph
25.4k2 gold badges26 silver badges37 bronze badges
answered Feb 23, 2013 at 17:22
\$\endgroup\$
9
  • \$\begingroup\$ Hah! You couldn't resist opening an account just for this :) \$\endgroup\$ Commented Feb 23, 2013 at 17:26
  • 2
    \$\begingroup\$ Yay I'm glad I motivated someone to joining in. Great way to start, also. That was the obvious thing I was missing, recursion! Adapting from your answer, I got the one-liner: function inc_str(str){ return (last(str) == "z") ? inc_str(head(str)) + "a" : head(str) + inc_char(last(str)); }; So elegant! Thank you. \$\endgroup\$ Commented Feb 23, 2013 at 17:42
  • \$\begingroup\$ @Dokkat you shouldn't write your code so condensed. \$\endgroup\$ Commented Feb 23, 2013 at 17:49
  • \$\begingroup\$ That's fine, this isn't meant to be human readable as it is the base of an AI programming system I'm developing. Less tokens = better and I must avoid varaibles. \$\endgroup\$ Commented Feb 23, 2013 at 18:12
  • \$\begingroup\$ @Dokkat, so you wrote it with your eyes closed? \$\endgroup\$ Commented Feb 23, 2013 at 19:14
1
\$\begingroup\$

I suppose this could be written as:

 function inc_str(str){
 return !/^[a-z0-9]$/i.test(str[str.length-1]) ? str :
 str.substr(0,str.length-1) + 
 ( /z/i.test(str[str.length-1]) 
 ? String.fromCharCode(str.charCodeAt(str.length-1)-25) 
 : String.fromCharCode(str.charCodeAt(str.length-1)+1))
}
// usage
inc_str('aaa'); //=> 'aab'
inc_str('aaz'); //=> 'aaa'
inc_str('aaZ'); //=> 'aaA'
inc_str('aa2'); //=> 'aa3'
answered Feb 28, 2013 at 6:22
\$\endgroup\$
1
  • \$\begingroup\$ Your code doesn't roll over. inc_str('az') outputs as "aa" but should be "ba" \$\endgroup\$ Commented Jul 2, 2013 at 2:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.