Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

RegEx not testing all characters

This is my whole program i want to process a string which contains alphabets and numbers some of which occurs in continuous fashion. For ex, let the input string be 1X7T4VrCs23k4vv08D6yQ3S19G4rVP188M9ahuxB6j1tMGZs1m10ey7eUj62WV2exLT4C83zl7Q80M

and i want the output to be 1Y7U4WsDt23l4ww08E6zR3T19H4sWQ188N9bivyC6k1uNHAt1n10fz7fVk62XW2fyMU4D83am7R80N

Basically what the do is that it rotates the orgnl array by the specified position and store it into the revArr. Now the input string is processed and the index of the input string is retrieved from the orgnl Array and the values at the retrieved index are printed as the output from the revArr. It only process the alphabets and also consider case sensitivity. If no. are encountered or any other non-word character is encountered it remains unaltered and printed as iT is in the output.

Problems i am facing:

  1. If two non-word character occurs together than the word next to the non-word character changes it position.
  2. The test condition for checking uppercase letters is not applying for all array elements.
  3. If a same non-word character appears twice in the input string than it counts it only once.

Can you please run my program and tell me where i am wrong in this program.

Please consider these test cases as inputs

Test Case 1:

Input: !m-rB-oN!.WcLAcVbN/CqSoolII!SImji.!w/XuuZa1TWPRquRBtokxPT`lL-zPTc.BSRIhu..-!.!tcl!-U

Expected Output: !w-bL-yX!.GmVKmFlX/MaCyyvSS!CSwts.!g/HeeJk1DGZBaeBLdyuhZD`vV-jZDm.LCBSre..-!.!dmv!-E

Test Case 2:

Input: DNFjxo?b5h*5<LWbgs6?V5{3M].1hG)pv1VWq4(!][DZ3G)riSJ.CmUj9]7Gzl?VyeJ2dIPEW4GYW*scT8(vhu9wCr]q!7eyaoy.

Expected Output: WGYcqh?u5a*5<EPuzl6?O5{3F].1aZ)io1OPj4(!][WS3Z)kbLC.VfNc9]7Zse?OrxC2wBIXP4ZRP*lvM8(oan9pVk]j!7xrthr.

Test Case 3:

Input: Pz-/aI/J`EvfthGH

Expected Output: Dn-/oW/X`SjthvUV

    let s = "1X7T4VrCs23k4vv08D6yQ3S19G4rVP188M9ahuxB6j1tMGZs1m10ey7eUj62WV2exLT4C83zl7Q80M"; // place your input string here.
    let k = 28; // change this number if you want to rotate the array with any other value.

    let alphabets = 'abcdefghijklmnopqrstuvwxyz';
    let orgnl = alphabets.split("");
    let revArr = alphabets.split("");
    let popedElements = [], index = [], outputString = [], output;

    let inputString = s;
    let caseString = inputString.split("");
    let str = inputString.toLowerCase().split("");
    // let pos = Number.parseInt(rotation.value);

    // For Regular Expressions
    let regEx = /[^a-zA-Z]/g;
    let popIn = [ ], tempPopIn = [ ], nonWord = [ ];

    // Storing the original index of the non Word character in popIn array
    for( let i = 0; i < caseString.length; i++ ){
        if( regEx.test(caseString[i]) ){
            popIn.push(i);
        }
    }

    // Storing the non word character from the original array to nonWord array
    popIn.forEach( (j) => nonWord.push(caseString[j]) );

    // Removing the non word character from the original array
    for( let i = 0; i < str.length; i++ ){
        if( regEx.test(str[i]) ){

            tempPopIn.push(i);
            tempPopIn.forEach( (j) => { 
                str.splice(j, 1);
                tempPopIn.pop();
            });
        }
    }

    // Rotating the original array by specified position
    for( let i = 0; i < k; i++ ){
        let remove = revArr.shift();
        revArr.push(remove);
    }

    // Finding index of input string in orgnl array and store it in an index array
    str.forEach( (i) => index.push(orgnl.indexOf(i)) );

    // Find the string at specified index in the rotated array
    index.forEach( (i) => outputString.push(revArr[i]) );

    // Making string from array
    for( let i = 0; i < popIn.length; i++ ){
        outputString.splice(popIn[i], 0, nonWord[i]);
    }

    // Checking letter case
    for( let i = 0; i < caseString.length; i++ ){
        if( caseString[i] === caseString[i].toUpperCase() ){
            outputString[i] = outputString[i].toUpperCase();
        }        
    }

    // Print the value to the output field
    output = outputString.toString().split(",").join("");    
    console.log(output);

1 Answer

Steven Parker
Steven Parker
229,657 Points

Something's getting lost in all the indexing because the output array is still sparsely populated when the case conversion is attempted, and it fails on the first element it encounters that is still undefined.

But the whole process seems seriously over-complicated. Instead, you could just iterate through the input string and for each letter, perform the necessary conversion (if any) and then add it to the output string. One loop, no need for regex, no conversion to arrays, and no separating word letters from non-word characters by index.

Can you please write me the code of what you are proposing.

Steven Parker
Steven Parker
229,657 Points

That's a rather big ask, but I'll do it this time:

let inputString =  // place your input string here:
  "1X7T4VrCs23k4vv08D6yQ3S19G4rVP188M9ahuxB6j1tMGZs1m10ey7eUj62WV2exLT4C83zl7Q80M";
let k = 28;  // change this number if you want to rotate the array with any other value

let orgnl = "abcdefghijklmnopqrstuvwxyz".split("");
let revArr = orgnl.slice();

// Rotating the original array by specified position
for (let i = 0; i < k; i++) {
  revArr.push(revArr.shift());
}

outputString = inputString.split("").map(a => {  // for each character
    let x = orgnl.indexOf(a);                    // if it matches as is,
    if (x >= 0) return revArr[x];                // rotate (lower case)
    x = orgnl.indexOf(a.toLowerCase());          // if it matches when converted,
    if (x >= 0) return revArr[x].toUpperCase();  // rotate upper case
    return a;                                    // otherwise leave it alone
  }).join("");

// Print the value to the output field
output = outputString.toString().split(",").join("");
console.log(output);

So now I'm curious, what's the practical use for this code?

Bravo Steven, The code worked very well. Thanks for sparing some time to get the best out of the mess i created :p .

Steven Parker
Steven Parker
229,657 Points

So does this have a practical application?

Actually, this is Caesar's cipher encrypting technique. I got this problem along with 3 more problems as assignment. Rest 3 are solved within minutes but this problem takes the maximum time almost 10-15 days. In last i tried this community help and finally you helped me. Thank you once again.

Steven Parker
Steven Parker
229,657 Points

So you got me to do your homework! :open_mouth:

Hahahahah not like that.