The most commonly used and perhaps most powerful higher-order functions are these "iterator" array methods:
arr.forEach — useful for performing some repetitive task for each value in the source array
arr.filter — useful for testing every value in the source array and keeping only the values that pass the test (e.g. only the even numbers in a numbers array)
arr.map — useful for transforming every value in the source array into another value (e.g. capitalize every string in an array of sentences);
Let's take a look at each of them. We can see how they are used and how we can create our own versions of them.
forEach
arr.forEach(callback) iterates over the source array and invokes the given callback with each value, that value's index, and the source array arr as inputs.
Use forEach to execute callbacks that produce side-effects (like printing to the console or mutating values).
Examples:
In this example, we want to print a message about each value and its location in the fruits array:
0-forEach.js
// print every fruit loudly!
const fruits = ['apples', 'bananas', 'cherries'];
const printLoudly = (input, index, arr) => {
console.log(`${input}!!! at index ${index} in array [${arr}]`);
}
fruits.forEach(printLoudly);
// print each fruit value capitalized
fruits.forEach(value => {
console.log(value.toUpperCase())
});
In this example, we provide an anonymous inline function. We have chosen to ignore the index and source array inputs and just focus on each user value in the users array:
Implement your own forEach function that takes an array and a callback and invokes the callback on every value in the array. The callback should be invoked with 3 inputs for every value:
const forEach = (array, callback) => {
for (let i = 0; i < array.length; i++) {
callback(array[i], i, array);
}
}
filter
arr.filter(callback) iterates over the source array, invoking the given callback with each value, index, and the source array arr as inputs. If the callback returns true, the value is added to an array which is returned.
Use filter when you want a copy of the source array with unwanted values removed.
Examples:
In this example, we want to know how many scores in an array of numbers are greater than or equal to 75. Using arr.filter, we can get a copy of the array containing only those passing scores and then read its length.
1-filter.js
const scores = [100, 85, 90, 70, 74];
// We only care about the value, the index and arr can be ignored
const isPassing = (score) => {
return score >= 75;
}
// This is a copy of scores that has been filtered.
const passingScores = scores.filter(isPassing);
// Using its length, we can get the number of passing scores
console.log(`There were ${passingScores.length} passing scores`);
In this example, we will have an array of user objects. We want to get a copy of the array that only contains admins. Filter lets us check each object and only those with isAdmin: true will pass the test and be returned in the new array.
Implement your own filter function that takes an array and a test callback and returns an array. The test callback should be invoked with 3 inputs for every value:
The current value
The current value's index in the source array
The source array itself
The test callback should be expected to return true or false. If test returns true, the value it was called on should be added to the returned array.
const filter = (array, test) => {
// Create a new array to be returned
const filtered = [];
for (let i = 0; i < array.length; i++) {
// If array[i] passes the test, add it to filtered
if (test(array[i], i, array)) {
filtered.push(array[i]);
}
// Otherwise, continue
}
// Return the filtered values only.
return filtered;
}
map
arr.map(callback) iterates over the source array, invoking the given callback with each value, index, and the source array arr as inputs. The value returned by the callback is added to an array which is returned.
Use map when you want a copy of the source array with each value converted to a new value.
Examples:
In this example, we have an array inchesArr containing values each representing a number of inches. Using arr.map, we transform each inches value into a string in the format x inches => y feet z inches. Each of these new strings is added to the array returned by map and stored in feetAndInches:
Implement your own map function that takes an array and a modify callback and returns an array. The modify callback should be invoked with 3 inputs for every value:
The current value
The current value's index in the source array
The source array itself
The modify callback should be expected to return a value that should be added to the returned array.
These are Higher Order Methods because they are functions stored within an Array "Object", not as a stand-alone function.
.forEach(callback)
Iterate through an array, but don't make a copy
Callback Should Accept
Callback Should Return
.forEach returns
The current value. Its index and the entire array are optional
nothing
undefined
const letters = ['a', 'b', 'c'];
const callback = (val, idx, arr) => {
console.log('Value at index:', val);
console.log('Current index:', idx);
console.log('Original array:', arr);
};
letters.forEach(callback);
// Value at index: a
// Current index: 0
// Original array: [ 'a', 'b', 'c' ]
// Value at index: b
// Current index: 1
// Original array: [ 'a', 'b', 'c' ]
// Value at index: c
// Current index: 2
// Original array: [ 'a', 'b', 'c' ]
.filter(testCallback)
Get ALL elements in an Array that pass a given test
Callback Should Accept
Callback Should Return
.filter returns
The current value. Its index and the entire array are optional
a boolean used to determine if the current element is kept