progTurd
progTurd

Reputation: 21

Array elements not mutating inside for of loop

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.

Upvotes: 1

Views: 470

Answers (3)

Gershom Maes
Gershom Maes

Reputation: 8150

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

Upvotes: 2

pretzelhammer
pretzelhammer

Reputation: 15115

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"

Upvotes: 1

user13782377
user13782377

Reputation:

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");

Upvotes: 1

Related Questions