How to pass a function only after an entire array has been read and not for each element?

Viewed 71

I'm trying to run a function when reading an array, but instead of running the function to each element, which I'm currently using forEach for, I want to make the script to read the entire array and then pass a function.

What I'm trying to say is this:

data.forEach(movie => {
    // Log each movie's title
    //console.log(movie.title);

    // Check if the userWord matches
    if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
        alert("YES");                   
    } else {
        alert("NO").
    }
});

Let's say my array is: array = ["Aa", "Ba", "Ca", "Da"];

If the user enters: a, then the script would alert("YES") four times, and I want to make it alert just once, at the end of the iteration.

For the same example, if the users enters: B, then the script would first alert("NO") once, then alert("YES"), then alert("YES") 2 times, and I want to make it just alert("YES")once, in the end.

Finally, if the users enters: Ferrari, then the script would alert("NO") four times, and I just want it to alert("NO") at the end.

I tried to make it very clear here, that's why the three "cases" of what is happening.

In the end, I want to know if there is a method that is kinda the opposite of the forEach or the common for. Something that just executes the function after reading the entire array.

4 Answers

I think closest what you can get is some. Here is example

let data = ["test","hello", "hello1"];
let userWord = "el";
let res =  data.some(movie => movie.toUpperCase().includes(userWord.toUpperCase()));
console.log(res) // prints true- means there was at least one "match", so you can alert

You could use the filter array function to filter array elements that match your criteria and then finally alert only if a match is found. Using this method you could get all the elements that have matched to your userWord. That is, the match array will contain all the possible matches.

var data = ['Aa', 'Bb', 'Cc', 'Dd'];
var flag = false;
var userWord = 'F'
var match = data.filter(movie => movie.indexOf(userWord) !== -1);
if(match.length)
console.log('YES');
else
console.log('NO');

  1. Change the alert to a bool variable
  2. Remove else (it would only overwrite any match)
  3. if bool statement outside the loop to perform actions

if you want a list of the results, you should store the names in an array and outside of the loop - print.

see below:

Non-loop method:

data = ["test","hello", "hello1"];
search = "lo"; 
const matches = data.filter(movie => movie.includes(search));

alert(matches) //array of only matches - only has hello and hello 1

I don't know if there are performance gains against a loop... I suppose you could do a side by side comparison on a large dataset

Loop method:

var matches = "";
data.forEach(movie => {
    // Check if the userWord matches
    if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
        matches += movie.title + "<br> ";
    }
});

if (matches.length > 0)
{
    document.getElementById("results").innerHTML = matches;
} else {
    alert("No match found");
}

You'll see more customization on the first loop, but I think filtering data first is the way to go.

If I understand the question correctly, I believe you want to execute something if a predicate matches at least one of the items in the array (correct me if I'm wrong). For that you can use the some method like so:

if (movies.some((movie) => movie.toUpperCase().includes(userWord.toUpperCase()))) {
  alert('YES');
} else {
  alert('NO');
}
Related