Joey Lee
Joey Lee

Reputation: 11

Can someone explain a forEach loop?

Ok, so here is what I do know about forEach.

a forEach loop pulls from the array and the function placed inside gets called on every element inside the array. I just can't seem to grasp the concept. I'm still learning JS and it's been a month so please be patient with me. I've tried using a for loop and it seems to work, I just dont know how to incorporate it as a forEach

function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

// Using a for loop

for(let i = 0; i < suspects.length; i++){
    suspectsList.push(CreateSuspectsObjects(suspects[i]))
};

Like i've said I'm still learning JS and dont really understand a forEach loop. I've tried suspects.forEach(CreateSuspectObjects), but it is just not making any sense to me.

Upvotes: 1

Views: 645

Answers (4)

Patrick Roberts
Patrick Roberts

Reputation: 51916

Transitioning your current code to work equivalently using Array.prototype.forEach() instead of a for loop requires a minimal change:

function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split(' ')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
}

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

// Using forEach()
suspects.forEach((name, i, suspects) => {
  // use name instead of suspects[i]
  suspectsList.push(CreateSuspectObjects(name))
});

console.log(suspectsList);

However, as you are creating a new array by transforming each object in an existing array, you should use Array.prototype.map() instead:

function CreateSuspectObjects (name) {
  return {
    name, // short-hand for name: name
    color: name.split(' ')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
}

const suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

// Using map()
const suspectsList = suspects.map(name => {
  return CreateSuspectObjects(name);
});

console.log(suspectsList);

You can condense this even more since name => { return CreateSuspectObjects(name); } does exactly the same thing as CreateSuspectObjects, by changing the statement to

const suspectsList = suspects.map(CreateSuspectObjects);

array.forEach() vs. array.map()

The reason that suspects.forEach(CreateSuspectObjects); did not work is due to the difference between forEach() and map(). forEach() loops over each value in suspects and executes the function provided for its side-effect. In my first snippet, the side-effect is suspectsList.push(), which adds a value to the existing array suspectsList.

However, CreateSuspectObjects() does not have any side-effects; it simply returns an object, which forEach() will ignore, since the return value of the function is not used.

The reason that suspects.map(CreateSuspectObjects); did work is because map() creates an array the same size as suspects, and loops over each value in suspects to execute the function provided for its return value. map() uses the return value of the function as the initializer for each respective value in the array that it created, then returns it.

Upvotes: 3

holydragon
holydragon

Reputation: 6728

You can use forEach to replace the for loop by using it like this.

It will iterate through the suspects array and refer to each of its object inside the array sequentially just like i++ does. Here I refer to each of them as suspect to make it easy to understand then you push it into the array just like what you do with suspects[i].

About the arrow operator, see here if you don't know how it works.

function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

suspects.forEach(suspect => suspectsList.push(CreateSuspectObjects(suspect)))
console.log(suspectsList)

Upvotes: 0

Jack Bashford
Jack Bashford

Reputation: 44125

A forEach loop is just a way to simplify a traditional for loop. You pass it a function, which is just whatever normally goes inside the {} of a for loop. However, with the function, you need to be aware of the parameter order:

item
index
array

This means that if you want the index of your item, not the item itself, you need to use the second parameter of the function:

arr.forEach((item, index) => doSomething.with(index));

Note that the above is called an arrow function, and it's a new ES6 feature. It's the equivalent of:

arr.forEach(function(item, index) {
  doSomething.with(index);
});

Upvotes: 3

see sharper
see sharper

Reputation: 12045

forEach is pretty simple. It is a property of any array, and calling it results in the function provided as a parameter being called for each item in the array. So for what you're after:

function CreateSuspectObjects (name) {
  return {
    name: name,
    color: name.split('')[1],
    speak() {
      console.log(`My name is ${name}`);
    }
  };
};

let suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];

let suspectsList = [];

suspects.forEach(s => {
    suspectsList.push(CreateSuspectsObjects(s))
};

Upvotes: 1

Related Questions