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

\$\endgroup\$
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).

\$\endgroup\$
  • \$\begingroup\$ Hah! You couldn't resist opening an account just for this :) \$\endgroup\$ – Benjamin Gruenbaum Feb 23 '13 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\$ – MaiaVictor Feb 23 '13 at 17:42
  • \$\begingroup\$ @Dokkat you shouldn't write your code so condensed. \$\endgroup\$ – copy Feb 23 '13 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\$ – MaiaVictor Feb 23 '13 at 18:12
  • \$\begingroup\$ @Dokkat, so you wrote it with your eyes closed? \$\endgroup\$ – radarbob Feb 23 '13 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'
\$\endgroup\$
  • \$\begingroup\$ Your code doesn't roll over. inc_str('az') outputs as "aa" but should be "ba" \$\endgroup\$ – Larry Battle Jul 2 '13 at 2:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.