Jay Jenkins
Jay Jenkins

Reputation: 423

Test fails when I include an array reference in regex (array with index in regex) JavaScript

I am doing a challenge on freeCodeCamp. I am passed an array with 2 strings, the instructions are to test to see if the letters in the second string are in the first string.

Here's what I have:

return /[arr\[1\]]/gi.test(arr[0]);

This passes all the tests except where it tries to match with a capital letter.

mutation(["hello", "Hello"]) should return true.

It's the only test that fails, I have tested my regex on regexr.com with:

/[Hello]/gi and it matches with 'hello'.

Yes, there are other ways to do it, but why does it fail when I pass the string into the regex from the array?

EDIT: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/mutations

Upvotes: 0

Views: 613

Answers (5)

Emeeus
Emeeus

Reputation: 5250

keep in mind that with this: return /[arr\[1\]]/gi.test(arr[0]) you are evaluating exactly this string "arr[1]". test() is a method of RegExp, then to add variables in a regex, or build the regex as string, you should use the RegExp constructor. Like the example below.

See this for browser compatibility of flags.

function mutation(str){

    var r = new RegExp(str[0].toLowerCase(), "gi")
    return r.test(str[1].toLowerCase());

}


console.log(mutation(["hello", "Hello"])) 

Upvotes: 2

Nick
Nick

Reputation: 147206

The fact that your code passes the test for ["Mary", "Army"] shows that the problem is not one of case sensitivity. The only reason your code passes any of the tests is that /[arr\[1\]]/ looks for matches against the set of characters ar1[] which coincidentally happens to correctly match 8 of the 9 tests. Anyway the other - perhaps biggest - issue is that you are not testing all of the characters in arr[1] against arr[0]; if you run @Emeeus's answer it returns false positives for many of the tests. So, to test all of the characters in arr[1] against arr[0] you need something like this:

function mutation(arr) {
  return arr[1].split('').reduce((t, c) => t && new RegExp(c, 'i').test(arr[0]), true);
}

let tests = [
  ['hello', 'hey'],
  ["hello", "Hello"],
  ["zyxwvutsrqponmlkjihgfedcba", "qrstu"],
  ["Mary", "Army"],
  ["Mary", "Aarmy"],
  ["Alien", "line"],
  ["floor", "for"],
  ["hello", "neo"],
  ["voodoo", "no"]
];

tests.map(arr => console.log(arr[0] + ", " + arr[1] + " => " + (mutation(arr) ? 'match' : 'no match')));

Upvotes: 1

Poul Bak
Poul Bak

Reputation: 10930

Instead of:

return /[arr\[1\]]/gi.test(arr[0]);

you can do:

return new RegEx(arr[1], gi);

Your code uses a character match ([ ]), not a string match, so it will match anything, that has those characters directly (That's why uppercase and lowercase differs, although you have specified 'i').

The new expression directly uses the string to match, not just the characters.

Upvotes: 0

victorocna
victorocna

Reputation: 1

Whenever you have a javascript variable in a regular expression, you should construct a new RegExp object. Taken from your question, it should look like this

return new RegExp(arr[1], "gi").test(arr[0]);

As one hint on freeCodeCamp.org says, you can solve the problem easier if you transform the strings into arrays, using the spread operator. No need for regular expressions.

Upvotes: 0

likle
likle

Reputation: 1797

JavaScript has a special syntax for Regular Expressions. Those two lines are essentially the same:

return /[arr\[1\]]/gi.test(arr[0]);
return new RegExp('[arr\\[1\\]]', 'gi').test(arr[0]);

but what you probably want is this:

new RegExp('['+arr[1]+']', 'gi').test(arr[0]);

However, you should be careful since this approach does not work if it contains special characters such as '[' or ']'.

Upvotes: 1

Related Questions