Iteration Methods
Open the project folder
In our starter files, open the index.html page from this lessons folder:
02.Arrays-In-More-Depth > 05.Iteration Methods
Why iteration is useful
This final group of methods loop over each item in the array and run a function for each one. They are useful when we have lot's of array items and we want to repeat a process for each value.
An example could be to check the permissions a user has for your site. This starter file has an array of permissions, if you have used WordPress before, these will look familiar:
// admin = full access & permissions
// author = can publish & manage their own posts
// subscriber = can only manage their own profile
let roles = ['admin', 'author', 'subscriber'];
This type of code is very common, we could set up a list of permissions users can have, then use JavaScript to check if a user has any of them before proceeding.
Imagine we had a user who created a new blog post on our site, and they hit the publish button. Before publishing, we first want to check they are allowed to publish. We can create a function to check this:
function canPublish(role) {
  // only admin & author can publish their own posts
  return role === 'admin' || role === 'author';
}
This will return true if the function is called with “admin” or “author” passed to it, otherwise false. You can test by adding a console log below the function:
console.log(canPublish('admin'));
Give this a try with author and subscriber passed to the function. We could then write some code to publish the post if true.
We have a problem with this already, this is a very manual task. We have to type in the roles manually when calling the array. Which then takes us back to the purpose of this lesson which is to look at iteration, or looping through our array values, so we don’t have to pass them in one by one.
The some() method
The first method is some, and this checks if some of the array values are a match:
let roles = ["admin", "author", "subscriber"];
function canPublish(role) {
  return role === 'admin' || role === 'author';
}
roles.some();
But a match for what? Using this example, we can move the canPublish function into the some method:
let roles = ["admin", "author", "subscriber"];
roles.some(function(role) {
  return role === 'admin' || role === 'author';
});
Also notice the function name of canPublish has been removed since we do not call it manually, instead it will be called once for each value in the array, often referred to as a callback function.
Each time the function is called, the “role” parameter is the current array value. The first loop will be “admin”, second it will be “author” and last of all “subscriber”.
Again, this is returning a true or false value, so we can store it into a variable, and console log:
let roles = ["admin", "author", "subscriber"];
const canPublish = roles.some(function (role) {
  return role === 'admin' || role === 'author';
});
console.log(canPublish);
This is true because at least one of the roles is a match. If none of these roles were included the result would be false.
The every() method
What if we want to only return true if all the array values are a match? For this use case, we have the every method. Here is an example:
let testScores = [117, 99, 122, 109];
const aboveAverage = testScores.every(function(number) {
  return number > 95;
})
console.log(aboveAverage);
This is an array of test scores. The every method will run a callback function for each value in the array, and it will return true if over the 95 average. For every to return true, all of the array items must be above 95, one value under will cause it to fail.
The findIndex() method
We may also see roles attached to a user object like this:
let users = [
  {
    user: '1',
    role: 'admin',
  },
  {
    user: '2',
    role: 'author',
  },
  {
    user: '3',
    role: 'author',
  },
  {
    user: '4',
    role: 'subscriber',
  },
];
This array contains multiple user objects inside. Using iteration methods we can loop through each one of these array values and return the ones we need. If we wanted to get an index number for a particular user, for this we can use the findIndex method.
let users = [
  {
    user: '1',
    role: 'admin',
  },
  {
    user: '2',
    role: 'author',
  },
  {
    user: '3',
    role: 'author',
  },
  {
    user: '4',
    role: 'subscriber',
  },
];
const index = users.findIndex(function (user) {
  return user.role === 'subscriber';
});
console.log(index); // expected output: 3
We call the findIndex method, on the user’s array, it will run a function for each value, and each one of these values is stored in the function’s user parameter. In the return statement, we access the user, select the role, and check if it is equal to subscriber. It will then return the array index position of the first match, for this example, it is index position 3.
The return value is stored into a variable and logged to the console. This returns the index position, but sometimes we may want the actual user value, such as the full object.
The find() method
If we needed to find the first value, such as the first author which matches our test, we have the find() method:
let users = [
  {
    user: '1',
    role: 'admin',
  },
  {
    user: '2',
    role: 'author',
  },
  {
    user: '3',
    role: 'author',
  },
  {
    user: '4',
    role: 'subscriber',
  },
];
const author = users.find(function (user) {
  return user.role === 'author';
});
console.log(author); // {user: '2', role: 'author'}
We call the find() method on our users array. This will run a function for each value. Here we check if the role is equal to author, and then will return the first object which is a match.
This returns user 2, which is the first matching user who has the role of author. But, as we know, there are two authors, user 2 and 3.
To fetch both, we have the filter method.
The filter() method
Using the same example as before, all we need to do is change find() to filter, and this will return all matches, meaning returned is a new array containing user 2 and 3:
const authors = users.filter(function (user) {
  return user.role === 'author';
});
Arrow functions
Since ES2015, we have a different type of function syntax we can use, called an arrow function. Arrow functions have some behaviour differences to a traditional function which we will look at in more detail in the functions section. But for now, we can use them to shorten our function code.
First, remove the function keyword, and place in an arrow (=>):
const authors = users.filter((user) => {
  return user.role === 'author';
});
We can also place this onto one line, remove the curly braces, and remove the return keyword, leaving this:
const authors = users.filter((user) => user.role === 'author');
This will return the value automatically. Finally, if we only have one parameter, we can also remove the brackets surrounding it:
const authors = users.filter(user => user.role === 'author');
If we pass in multiple parameters, we must still use the brackets. This shorter syntax is often used to keep things like this shorter, so you will come across examples like this too.
We have now covered some of the popular array methods, there are still a few more too but they all generally work in a similar way. There are also more of these iteration methods that we will look at in more detail later.