I'm trying to replace every letter in the string with the letter following it in the alphabet.
example:
a -> b
b -> c
c -> d
and so on.
function LetterChanges(str) {
for (var i = 0; i < str.length; i++) {
if (96 < str.charCodeAt(i) && str.charCodeAt(i) < 123) {
str = str.replace(str.charAt(i), String.fromCharCode(str.charCodeAt(i) + 1));
}
}
return str;
}
so I test is with some string input, I got error on "cod", my code returned "epd" instead of "dpe", can someone please help me with fixing it?
Thanks.
Let's see what the code will do with input cod
:
c
, next letter in alphabet is d
, replace c
for d
, result is dod
o
, next letter in alphabet is p
, replace o
for p
, result is dpd
d
, next letter in alphabet is e
, replace d
for e
, result is epd
You see the error at step 3? replace
replaces first occurence of the letter the way you use it. One solution would be to create new string by appending the next letters to it. For instance:
var newString = '';
for (var i = 0; i < str.length; i++) {
if (96 < str.charCodeAt(i) && str.charCodeAt(i) < 123) {
newString += String.fromCharCode(str.charCodeAt(i) + 1);
}
}
return newString;
By the way, your code also has one subtle bug. If your string contains z
it will be replaced for {
. You probably want to go back to the beginning of the alphabet and replace it for a
in that case.
Since your replace
is not restricted to specific positions within the string, it will replace the first matching character each time. (It does not replace all, because it does not have the g
modifier set.) So first your leading c
gets replaced by d
, the next round replaces the o
by p
– and then, in the third round, when your input is already dpd
, you get epd
as a result, because the first d
has been replaced by e
.
This would be easier, if you did not use replace
, but simply build a new string, that you append the matching “next” character for your current input character to each time, and then at the end you simply return that new string.
Edit:
Also, you current implementation does not handle z
correctly, since it replaces it with the “next” character {
, whereas that should rather be an a
. And Z
becomes [
, should be A
instead. And between Z
and a
, there is also a couple of non-letter characters, that you probably don’t want to replace as well.
Here is a function that implements what I suggested above, and also takes z
and Z
, and the non-letters into account:
function LetterChanges(str) {
var result = "";
for (var i = 0; i < str.length; i++) {
// handle "z"
if (122 == str.charCodeAt(i)) {
result += "a";
// handle "Z"
} else if (90 == str.charCodeAt(i)) {
result += "A";
// handle all other letter characters
} else if ((65 <= str.charCodeAt(i) && str.charCodeAt(i) <= 89) ||
(97 <= str.charCodeAt(i) && str.charCodeAt(i) <= 121)) {
result += String.fromCharCode(str.charCodeAt(i) + 1);
// append all other characters unchanged
} else {
result += str.charAt(i);
}
}
return result;
}
console.log(LetterChanges("AaZz+cod!foo")); // output: BbAa+dpe!gpp
http://jsfiddle.net/hvyft64p/3/
if ((65 <= str.charCodeAt(i) && str.charCodeAt(i) <= 89) ||
(97 <= str.charCodeAt(i) && str.charCodeAt(i) <= 121))
I used 65/89 and 97/121, and <=
for comparison here, since it just makes a little more sense to me from a logical point of view – these are the actual “boundary” letters we want to take into account here, A/Y and a/y, so using those numbers directly makes the code a little more readable IMHO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With