1

function rot13(str) {
  let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
  let n = 13;
  let arr = str.split("");
  let len = alphArr.length;

  for (let i of arr) {
    if (alphArr.includes(i)) {
      if (alphArr.indexOf(i) + n <= len - 1) {
        i = (alphArr[alphArr.indexOf(i) + n])
        console.log(i) // This is as expected
      }
    }
  }

  console.log(arr) // Array itself did not mutate and is showing the initial array. 
  return str;
}

rot13("SERR PBQR PNZC");

The value of i inside the second if statement is proper as can be seen in the console.log statement but the array in itself did not mutate. Why was that?

P.S. I've solved it by using map function and it works properly because map function does not mutate the original array.

8
  • what are you trying to do and what is the expected result? Commented Jun 23, 2020 at 15:43
  • Try console.log alphArr[alphArr.indexOf(i)+n] Commented Jun 23, 2020 at 15:46
  • 4
    assigning to i does not change the array. You are merely reassigning an unrelated variable in this case. Commented Jun 23, 2020 at 15:46
  • 1
    It's the value of the current array item. However, changing it won't change the array, since JavaScript is not pass-by-reference Commented Jun 23, 2020 at 16:16
  • 1
    @VLAZ Now I get it. Its due to the pass by value as its just represents the value of the element. Thank you so much for the clarification! Commented Jun 23, 2020 at 16:20

3 Answers 3

2

It's worth mentioning that your code can be simplified:

let rot = (str, n, asciiStart='A'.charCodeAt(0), asciiEnd='Z'.charCodeAt(0), asciiRange=asciiEnd-asciiStart+1) =>
  str.split('')
    .map(c => {
      let code = c.charCodeAt(0) - asciiStart;
      if (code >= 0 && code <= asciiRange) code = (code + n) % asciiRange;
      return String.fromCharCode(asciiStart + code);
    })
    .join('');

let inp = document.getElementsByTagName('input')[0];
let p = document.getElementsByTagName('p')[0];

inp.addEventListener('input', () => p.innerHTML = rot(inp.value, 13));
<input type="text" placeholder="test here (use capital letters)"/>
<p></p>

Your code wasn't working because replacing the value of i does not effect the array index that i was initially based off of. Once you define i, it doesn't remember how it was defined (e.g. it doesn't think to itself, "I originated from a value within an array')

Sign up to request clarification or add additional context in comments.

Comments

1

You can't directly set value to element in for of loop try the following...

function rot13(str) {
  let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

  let n = 13;
  let arr = str.split("");
  let len = alphArr.length;

  let j=0
  for (let i of arr) {
    if (alphArr.includes(i)) {
      if (alphArr.indexOf(i) + n <= len - 1) {

        arr[j]= (alphArr[alphArr.indexOf(i) + n])
        console.log(i) // This is as expected

      }
    }
    j++
  }
  console.log(arr) // Array itself did not mutate and is showing the initial array. 


  return str;
}

rot13("SERR PBQR PNZC");

8 Comments

If you are going to use a loop counter, you may as well use a regular loop for (let i = 0; i < arr.length; i++) and use arr[i] inside it. Mixing a for..of and counters is just messy. A better solution would be to just iterate over the entries in the array, which includes the index: for (let [index, element] of arr.entries())
Yes I would have done that for my code but here I used the code which was provided by the questioner.
Sorry for messy solution
I didn't know that you couldn't do and I didn't find any documentation saying it can't be done. Please share if you have if you find something.
The element in for of loop only contains the value of a particular property you can see it on MDN docs.
|
1

Instead of using a for of loop you should use map to create a new array and used the newly mapped array. Fixed fulling working example:

function rot13(str) {
  let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

  let n = 13;
  let arr = str.split("");
  let len = alphArr.length;

  arr = arr.map((i) => {
    if (alphArr.includes(i)) {
      let index = (alphArr.indexOf(i) + n) % len;
        return alphArr[index];
      }
     return i;
  });

  return arr.join("");
}

console.log(rot13("SERR PBQR PNZC")); // logs "FREE CODE CAMP"

2 Comments

I did solve it with map as it does not mutate the original array as Matt pointed out but I'm just confused as to why the original array did not get mutated in this case.
I got the answer thanks to VLAZ. It's because of the pass by value thing and that's why alphArr[alphArr.indexOf(i)+n] would work.

Your Answer

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.