skip to Main Content

I’m trying to develop a modular function that check if a string matches with a slice of RegExp.
As a matter of context:

// Object containing regular expressions
const regex = {
    uppercase: /(?=.*[A-Z])/,  // Find Capital letters
    digits: /(?=.*d)/,        // Find Digits
};

// Text to be compared
const text = "Hello World";  // It contains Capital and lowercase letters

// Call to function
console.log(contains(text, regex.uppercase, regex.digits));  // Expected output: `true` because the 'H' and 'W'

The problem is when I compare the RegExp’s slice using forEach(), as this:

function contains(str, ...pattern) {  // Receive the Text to be compared and a slice with RegExp
    pattern.forEach((regex) => {  // Loop for each RegExp in pattern slice
        if (regex.test(str)) {  // Check if a RegExp is in `str`
            return true;  // `true` if any RegExp matches
        }
    });

    return false;  // Return `false` if no one Expression is in the string
}

In this case I compared if is any Capital letter or digit in the string, but this code always returns false. And I don’t know what I’m doing bad. Instead, this code using for of works:

function contains(str, ...pattern) {  // Receive the Text to be compared and a slice with RegExp
    for (const regex of pattern) {  // Loop for each RegExp in pattern slice
        if (regex.test(str)) {  // Check if a RegExp is in `str`
            return true;  // `true` if any RegExp matches
        }
    }

    return false;  // Return `false` if no one Expression is in the string
}

When I compare in contains() ussing the forEach() loop, it always returns false as it doesn’t match with the RegExp. But the for of loop works perfectly.

Even though it seems to me that they do the same thing.

Why the first method doesn’t works?

2

Answers


  1. The first method doesn’t work because you pass the code to execute on each element as a callback function and forEach does not care about its return value. return only returns from the nearest enclosing function and in your case, it returns from the forEach callback function. The return value is ignored by forEach and the outer function (contains) is not affected at all.

    It should be noted that the appropriate array method to use here is Array#some, which checks if the callback function provided returns a truthy value for any element in the array.

    function contains(str, ...pattern) {
      return pattern.some(p => p.test(str));
    }
    const regex = {
        uppercase: /(?=.*[A-Z])/,
        digits: /(?=.*d)/,
    };
    const text = "Hello World";
    console.log(contains(text, regex.uppercase, regex.digits));
    Login or Signup to reply.
  2. why make the code so complicated when the library is already provided in the browser. the function of forEach is to change the value of the caller. and does not return any value. as an example. i suggest to use .map instead of .forEach

    // Text to be compared
    const text = "Hello World-12a"; 
    // find `UpperCase` and `digit`
    // /[A-Z]/g -> find UpperCase
    // /[*d]/g or /[0-9]/g -> find digit
    var test = text.match(/[A-Z(*d)]/g)
    console.log(test) // ['H','W','1','2']
    let contains = (function(){
        return text
        .match(/[A-Z(*d)]/g)
        .map(e => text.includes(e)).length != 0
    })();
    console.log(contains) // true
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search