Reputation: 11
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
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
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
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
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