Erik L
Erik L

Reputation: 195

I am having trouble converting a for loop to a forEach loop

I am new to programming and I would like to convert the following for loop to a foreach loop, this is the for loop:

checkLetter(letter) {
    //give the letter class a variable named letters to have a reference to them
   var letters = $('.letter');

   for (var i=0; i < letters.length; i++) {
       console.log(letters[i].innerHTML);
        //if the phrase contains a letter from the phrases array return true, otherwise it will return false
       if(letter === letters[i].innerHTML) {
        console.log('this is true')
        return true
       }
       else return false
    }
}

and this is what I wrote for the forEach version:

checkLetter(letter) {
    //give the letter class a variable named letters to have a reference to them
    var letters = $('.letter');
    //loop through each letter using Foreach
    letters.forEach(letter)
    console.log(letters[i].innerHTML);
    //if the phrase contains a letter from the phrases array return true, otherwise it will return false
    if(letter === letters[i].innerHTML) {
        console.log('this is true')
        return true
    }
    else return false
}

However, I ended up getting the following error:

letters.foreach is not a function

could someone please help?

Upvotes: 1

Views: 114

Answers (4)

Muhammad Ashikuzzaman
Muhammad Ashikuzzaman

Reputation: 3143

You can use Jquery .each function.

$( ".letter" ).each(function( index ) {
if(letter === $( this ).html()) {
        console.log('this is true')
        return false; // this will stop the execution
       } 
});

Upvotes: 0

Pablo
Pablo

Reputation: 6048

Since all the loop answers have been given I am going to propose a different approach. I suggest that you convert all the matching nodes .letter into a string and use indexOf to determine whether there is a match. Ex:

function checkLetter(letter) {
  return $('.letter').text().indexOf(letter) > -1;
}

console.log('A', checkLetter('A'));
console.log('C', checkLetter('C'));
console.log('F', checkLetter('F'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="letter">A</span>
<span class="letter">B</span>
<span class="letter">C</span>
<span class="letter">D</span>
<span class="letter">E</span>

Upvotes: 0

Dacre Denny
Dacre Denny

Reputation: 30360

An approach based on forEach() would not be a good fit for your problem as it will make "early returns" during your the forEach() loop difficult.

Perhaps you could consider using some() which returns true if an item in the iteration satisfies a provided condition:

return node.innerHTML === letter

Using some(), you could implement your checkLetter() function via the following:

function checkLetter(letter) {
  
  // Query document for .letter nodes. This avoids the need for jQuery
  var letters = document.querySelectorAll('.letter');

  // Convert letters selection result to Array via Array.from, and 
  // then call some() to determine if at least one node satisfies
  // the match condition "node.innerHTML === letter"
  return Array.from(letters).some(function(node) {

    return node.innerHTML === letter
  })
}


console.log('Check A:', checkLetter('A'))
console.log('Check B:', checkLetter('B'))
console.log('Check Z:', checkLetter('Z'))
<div class="letter">A</div>
<div class="letter">B</div>
<div class="letter">C</div>
<div class="letter">D</div>

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370689

letters is a jQuery object, not an array; to loop over a jQuery object, you'll either have to use a jQuery method, like each:

letters.each((i, letter) => {
  // do something with `letter`

or call Array.prototype.forEach:

Array.prototype.forEach.call(
  letters,
  letter => {
    // do something with `letter`
  }
);

Also note that your current letters.forEach(letter) doesn't make sense - forEach accepts a callback function as a parameter.

For what you're trying to achieve, though, it would be more appropriate to use Array.prototype.some to check if any if the items in letters fulfill the condition: forEach is more appropriate for generic iteration, when other array methods don't suffice:

checkLetter(letterToFind) {
  var letters = $('.letter');
  return Array.prototype.some.call(
    letters,
    letterElement => letterElement.textContent === letterToFind
  );
}

Or, less appropriate IMO but would still work, using jQuery's each:

checkLetter(letterToFind) {
  var letters = $('.letter');
  let foundLetter = false;
  letters.each((i, letterElement) => {
    if ($(letterElement).text() === letterToFind) {
      foundLetter = true;
    }
  });
  return foundLetter;
}

Upvotes: 1

Related Questions