Hi everyone,
I was able to solve the project Caesars Cipher but there are two things I still don’t quite understand and was wondering if anyone could help explain what is causing the issues, thanks in advance.
Link to challenge: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/caesars-cipher
I’ve blurred out the code below to avoid spoiling it for anyone.
My solution:
function rot13(str) {
const alphabet = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z" ];
console.log(alphabet);
let arrStr = str.split("");
// Array(11) [ "S", "E", "R", "R", " ", "C", "V", "M", "M", "N", … ]
console.log(arrStr);
// This regex will search for all letters in the alphabet, uppercase and
// lowercase, and also numbers. The "g" flag indicates that the regex should
// be tested against all possible matches in a string.
// Don't understand why I can't have /[A-Za-z0-9]/g; --> which is what I initially tried
let regex = /[A-Za-z0-9]/;
let result = [];
console.log(arrStr.length);
for (let i = 0; i < arrStr.length; i++) {
let placeInArray;
if (regex.test(arrStr[i])) {
placeInArray = alphabet.indexOf(arrStr[i]); // "S" should be at 18
if (placeInArray + 13 <= 25) {
result.push(alphabet[placeInArray + 13]);
} else if (placeInArray + 13 > 25) {
result.push(alphabet[placeInArray + 13 - 26]);
}
} else {
result.push(arrStr[i]);
}
}
result = result.join("");
console.log(result);
return result;
}
// Testing this instead of the default in the challenge since it has an exclamation mark.
rot13("SERR CVMMN!");
The thing I don’t understand is why adding a “g” to the regex results in “FEER PVZMA!”.
From reading MDN, the “g” flag in regex means the regex should be tested against all possible matches in a string. Since in the code I have:
if (regex.test(arrStr[i]))
I’m testing against each letter in the array “arrStr”. I understand at each index there’s only a single letter, so that means we don’t really need the “g” flag to find multiple matches. Having said that, I still don’t understand why we can’t have a “g” anyway, even if it’s not necessary.
My understanding is when we go through “arrStr[i]”, at each index there’s only a single letter. If we have “g” in the regex, we’re looking to see if there are multiple matches when looking at each individual letter. It can’t have more than one match given it’s a single letter, but I’m surprised that adding the “g” breaks the code.
I’d be most grateful if someone could shed some light on why adding the “g” doesn’t work, thanks in advance.
The second thing I’m confused about is while I was trying to come up with the solution, I tried the following (just for testing purposes) and was surprised by the result:
function rot13(str) {
const alphabet = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z" ];
console.log(alphabet);
let arrStr = str.split("");
console.log(arrStr); // Array(11) [ "S", "E", "R", "R", " ", "C", "V", "M", "M", "N", … ]
// Don't understand why I can't have /[A-Za-z0-9]/g;
let regex = /[A-Za-z0-9]/g;
// This doesn't work! Very strange...
for (let i = 0; i < arrStr.length; i++) {
if (regex.test(arrStr[i])) {
console.log(arrStr[i]);
}
}
}
rot13("SERR CVMMN!") // console: S
// console: R
// console: C
// console: M
// console: N
I was expecting the console to log exactly what is in the array “arrStr”, each letter at a time, ie “S”, “E”, “R”, “R”, “C”, “V” etc.
But it turns out it would only log the first letter and every other letter, skipping letters in between.
I’d be most grateful if someone could help explain what is happening here, thanks in advance.