Skip to main content

Array Iterator Methods Walk-Through

Learning Objectives​

Students Will Be Able To:
Identify the Purpose (Use Case) of Several Useful Array Iterator Methods

Videos​

Video 📹 Link

Intro​

JavaScript Arrays have lots of helpful built-in methods.

These methods enable us to write code following a modern functional programming approach verses that of imperative programming.

Imperative Programming​

Imperative programming is a more step-by-step way of writing code.

for loops, for example, are imperative:

for (let index = 0; index < array.length; index++) {
// do stuff
}

With a for loop we're saying:

  1. Initialize a looping variable
  2. Use the looping variable to access an element in the array
  3. Increment the looping variable
  4. If the looping variable is less than the length of the array, loop again

Functional/Declarative Programming​

In functional/declarative programming, we write code that describes what we want to do:

array.forEach(function(val, idx) {
// do stuff
});

How are we iterating? We, don't need to worry about that.

Method Summary​

MethodPurposeReturnsCallback ShouldCallback's Args
forEach(cb)General purposeundefinedDo whatever needs to be done(elem, idx)
map(cb)Transform source array into a new arrayNew arrayReturn what goes in the new array(elem, idx)
filter(cb)Filter source arrayNew arrayReturn truthy value if current elem is to be included in new array(elem, idx)
find(cb)Find a certain elementThe "found" elem, otherwise undefinedReturn truthy when elem is "found"(elem, idx)
findIndex(cb)Find the index of a certain elementThe index of the first elem "found", otherwise -1Return truthy when elem is "found"(elem, idx)
some(cb)Check if at least one element matches a conditiontrue or falseReturn truthy if elem is what you're checking for(elem, idx)
every(cb)Check if every element matches a conditiontrue or falseReturn truthy if elem is what you're checking for(elem, idx)
reduce(cb, initAcc)Reduce the array to a single value/objectFinal value of acc (accumulator)Return the new value of acc for the next iteration(acc, elem, idx)

Observations​

The following observations will make it easier to remember the syntax of these important methods...

  • Each of the methods invoke a callback function for each iteration.

  • Most methods have to iterate over the entire array in order to fulfil their purpose, however, the following methods will "short circuit" and stop iterating once their return value has been determined:

    • find: Stops iterating when the callback returns a truthy value
    • findIndex: Stops iterating when the callback returns a truthy value
    • some: Stops iterating when the callback returns a truthy value
    • every: Stops iterating when the callback returns a falsy value
tip

VOCAB: Note that the filter, find, findIndex, some and every iterator methods rely on the truthy-ness or falsy-ness returned by the callback function. In programming, a function designed to return true or false is called a predicate function.

  • All of the iterator methods, except reduce, have identical signatures, that is, they all accept a single argument - a callback function.

    Additionally, the signature of that callback functions are all the same as well!

Code Examples​

forEach​

PURPOSE: General purpose iterator method.

const friends = ["Melissa", "Marc", "Andrew", "Nick"];

friends.forEach(function(friend) {
console.log(`I have a friend named ${friend}`);
});

// logs out "I have a friend named <friend's name>" for each friend

YOU DO​

Using forEach log out each of my friends but with the first letter of their name lower-cased. Use the <str>.toLowerCase() method.

"Cats".toLowerCase(); //=> cats

map​

PURPOSE: Create a new array from a source array by replacing or transforming its elements.

The returned array is always the same length as the source array.

Transform an array​

const nums = [1, 2, 3];
const squared = nums.map(function(num) {
return num * num;
});

// squared -> [1, 4, 9]

/*--- using an arrow function for the callback ---*/
const squared = nums.map((num) => num * num);
The new elements can be anything​

Here we want to map an object of "people" objects into an array of DOM elements:

const people = [
{name: 'Fred', town: 'Bedrock'},
{name: 'Susan', town: 'Miami'},
{name: 'John', town: 'Arcadia'}
];

const els = people.map((person, idx) => {
const el = document.createElement('div');
el.innerHTML = `${person.name} <span>(${person.town})</span>`;
// The new array will contain whatever
// is returned from the callback
return el;
});

// Append the <div>s to the end of the <body>
els.forEach(el => document.body.append(el));

YOU DO​

Given an array of instructors,

const instructors = ["Alex", "Stephanie", "Daniel"];

Use map to create a new array that adds the string " is awesome" to each element in the array.

["Alex is awesome", "Stephanie is awesome", "Daniel is awesome"]

filter​

PURPOSE: Select certain elements from a source array.

Obtain just the odd numbers​

const nums = [100, 2, 5, 42, 99];
const odds = nums.filter((num) => num % 2);

// odds -> [5, 99]

YOU DO​

Filter out all "jerks"!

const people = ["jerks", "nice people", "jerks", "nice people", "nice people"];

find​

PURPOSE: Find an element within an array.

Find a certain car object​

const cars = [
{color: 'red', make: 'BMW', year: 2001},
{color: 'white', make: 'Toyota', year: 2013},
{color: 'black', make: 'Ford', year: 2014},
{color: 'white', make: 'Tesla', year: 2016}
];

const firstWhiteCar = cars.find((car) => car.color === 'white');
// firstWhiteCar -> {color: 'white', make: 'Toyota', year: 2013}

const missingCar = cars.find((car) => car.color === 'blue');
// missingCar -> undefined

YOU DO​

Find the first car whose year is older than 2014 and assign it to a variable named notTooOldCar;


findIndex​

PURPOSE: Like find above, but returns the found element's index instead of the element. Note that this is usually used to find the index of an object, or one of its built-in variations (Array, Date, Regular Expression, Error) within the array. If trying to find the index of a primitive type, use indexOf instead.

Find the index of the first match​

const cars = [
{color: 'red', make: 'BMW', year: 2001},
{color: 'white', make: 'Toyota', year: 2013},
{color: 'black', make: 'Ford', year: 2014},
{color: 'white', make: 'Tesla', year: 2016}
];

const idxFirstCarNewerThan2015 = cars.findIndex((car) => car.year > 2015);
// idxFirstCarNewerThan2015 -> 3

// findIndex returns -1 if callback never returns a truthy value
const missingCarIdx = cars.findIndex((car) => car.year > 2020);
// missingCarIdx -> -1

some​

PURPOSE: Check if array has at least one element that meets a certain condition.

Henry would be proud...

const cars = [
{color: 'red', make: 'BMW', year: 2001},
{color: 'white', make: 'Toyota', year: 2013},
{color: 'black', make: 'Ford', year: 2014},
{color: 'white', make: 'Tesla', year: 2016}
];

const hasFord = cars.some((car) => car.make === 'Ford');
// hasFord -> true

YOU DO​

Do I have an evil monkey in my room?

const myRoom = ["evil monkey", "bed", "lamp"];
const isEvilMonkeyInRoom = /* Fill code in here */

every​

PURPOSE: Check if every element in the array meets a certain condition.

Are all cars newer than 2000?​

const cars = [
{color: 'red', make: 'BMW', year: 2001},
{color: 'white', make: 'Toyota', year: 2013},
{color: 'black', make: 'Ford', year: 2014},
{color: 'white', make: 'Tesla', year: 2016}
];

const everyCarIsNewerThan2000 = cars.every((car) => car.year > 2000);
// everyCarIsNewerThan2000 -> true

reduce​

PURPOSE: Reduce an array into a single value or thing (such as an object).

Sum up the numbers in an array​

const nums = [25, 6, 100, 3];

// The callback returns the value of
// acc (accumulator) for the next iteration.
// The second argument, `0`, is the value
// of acc on the first iteration.
const sum = nums.reduce((acc, num) => acc + num, 0);

// The reduce method returns whatever the callback
// returns for the last iteration.
// sum equals 134 (the final value returned)
Count votes​

The reduce method can return any single thing, such as an object!

const votes = ['Yes', 'No', 'No', 'Yes', 'Yes'];
const tally = votes.reduce((acc, vote) => {
// Assign 1 if first time seeing a certain "type" of vote
// otherwise increase count by 1
acc[vote] = acc[vote] ? acc[vote] + 1 : 1;
return acc;
}, {}); // Note the initial value is an empty object

// tally -> {"No": 2, "Yes": 3}

Reference​

Array Reference on MDN