1

My goal is to advance each letter by three, for example, 'a' becomes 'd' and 'z' becomes 'c' etc. and ignore characters which are not letters. I am having trouble understanding the for loop and the if/else if/else statements that follow regarding my variable char. I also do not understand why I am getting lc.indexOf(char) = -1, as though its not even in my array.

Here is a sort of timeline regarding what I have tried:

I converted the strings to arrays because JS would not accept a string in a for loop, as in char in str...it would tell me it needed to be an object so I used the .split() function.

I checked that my arrays were correct with window prompts.

I changed the variable 'increase' to 2 and 4 and got 3 b's and d's respectively.

I checked the indexOf(char) within the if statements and they return -1.

It does not appear that variable char ever gets past the initial if statement...even if var str = ZZ2, I will still get all lowercase answers.

I have been programming for only 3 weeks, so please help me to understand not only how to do this in JavaScript, but why it's not working and why the correct method DOES work properly.

<p id="response"></p>
//I want to advance these characters by 3, ignoring the !
<script>
var str = "2Za";
var lowercase = "abcdefghijklmnopqrstuvwxyz";
var uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var increase = 3;
var answer = "";
var strarr = str.split("");
var lc = lowercase.split("");
var uc = uppercase.split("");
var char;
for (char in strarr) {
    if (char in lc) {
      answer += lc[(lc.indexOf(char) + increase) % 26];
    } else if (char in uppercase) {
      answer += uc[(uc.indexOf(char) + increase) % 26];
    } else {
      answer += char;
    }
  }

document.getElementById("response").innerHTML = answer

</script>

I am getting all lowercase 'ccc' or whichever letter corresponds to my var increase

halfer
  • 19,824
  • 17
  • 99
  • 186
Jerry Pass
  • 105
  • 12
  • 2
    [for...in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) iterates over property *keys* of an object in an arbitrary order, [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) iterates over property values. – crashmstr Jun 19 '19 at 16:37
  • There is a small error in the code I didn't change back to the original while I was working on this this morning.....;for the else if (char in uppercase)….it says else if (char in uc) for my current code – Jerry Pass Jun 19 '19 at 16:38

2 Answers2

0

Two issues:

  1. You're trying to use for-in to loop through an array. That's not what for-in is for, do one of these things instead.

  2. Another issue is here:

    if (char in lc) {
    

    The in operator doesn't check to see if a value is in an array, it checks to see if a property exists in an object (directly, or in its prototype chain).

    Instead, get the index, which will be -1 if not found:

    index = lc.indexOf(char);
    if (index != -1) {
        answer += lc[(index + increase) % 26];
    //                                    ^^--- I'd probably also use lc.length here
    //                                          rather than a hardcoded value
    }
    

    (And of course the same for the uc check.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Just to add to T.J.'s answer, there's a few more points you might find useful

first of all, you don't need to split the strings! You can treat them as an array, using length, indexOf and everything else. No need for the split("") function.

Furthermore, though it's true you don't want to use "in", you do want to use "of", as in

for (char of str)

After that, you do indeed want to use indexOf. Here's a snippet showing the code in action:

var str = "2Za";
var lowercase = "abcdefghijklmnopqrstuvwxyz";
var uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var increase = 3;
var answer = "";
var char;
for (char of str) {
    if (lowercase.indexOf(char) > -1) {
      answer += lowercase[(lowercase.indexOf(char) + increase) % 26];
    } else if (uppercase.indexOf(char) > -1) {
      answer += uppercase[(uppercase.indexOf(char) + increase) % 26];
    } else {
      answer += char;
    }
  }

document.getElementById("response").innerHTML = answer
<p id="response"></p>
Michael Beeson
  • 2,840
  • 2
  • 17
  • 25