Making Arrays More Functional

We previously covered 2 "classes" of Array methods

  • Mutator Methods - Those that change the structure of an Array 
  • Accessor Methods - Those that access contents of the Array without changing it

We have one left...

Iterator Methods

These methods iterate over the array

forEach(callback[, arg])

Calls a function you provide for each element in the Array

function logTheThings(element, index, array){
    console.log('Current element is: ', element);
}

var myArray = [3, 'taco', false, 'Wonka'];

myArray.forEach(logTheThings);

//Current element is: 3
//Current element is: 'taco'
//Current element is: false
//Current element is: 'Wonka'

Your callback function takes 3 params:

  • element - the current element being iterated over
  • index - the current index of the element in the Array
  • array - the array itself being traversed
var myArray = [3, 'taco', false, 'Wonka'];

myArray.forEach(function(element, index, array) {
    console.log('Current element is: ', element);
});

//Current element is: 3
//Current element is: 'taco'
//Current element is: false
//Current element is: 'Wonka'

=>

TIP: If you don't want the function to run against an element return false

every(callback[, arg])

Returns true if every element in the Array passes the test you provide

Your callback function takes 3 params:

  • element - the current element being iterated over
  • index - the current index of the element in the Array
  • array - the array itself being traversed
function isNumeric(element, index, array) {
    return !isNaN(parseInt(element));
}

var myArray = [3, 'taco', false, 'Wonka'];

myArray.every(isNumeric); //return false

var myOtherArray = [3, 5, 6, 9];

myArray.every(isNumeric); //return true

some(callback[, arg])

Returns true if ANY element in the Array passes the test you provide

Your callback function takes 3 params:

  • element - the current element being iterated over
  • index - the current index of the element in the Array
  • array - the array itself being traversed
function hazNumber(element, index, array) {
    return !isNaN(parseInt(element));
}

var myArray = [3, 'taco', false, 'Wonka'];

myArray.some(hazNumber); //return true, 1 iteration

var myOtherArray = ['test', 'taco', 'hotdog', {}];

myOtherArray.some(hazNumber); //return false, 4 iterations

Returns immediately when first true is found

filter(callback[, arg])

Creates and returns a new array with all elements that pass true test

Your callback function takes 3 params:

  • element - the current element being iterated over
  • index - the current index of the element in the Array
  • array - the array itself being traversed
function getNumberz(element, index, array) {
    return !isNaN(parseInt(element));
}

var myArray = [3, 'taco', false, 44, 'Wonka'];

myArray.filter(getNumberz); //return [3, 44]

console.log(myArray); //[3, 'taco', false, 44, 'Wonka']

var myOtherArray = ['test', 'taco', 'hotdog', {}];

myOtherArray.filter(getNumberz); //return []

console.log(myOtherArray); //['test', 'taco', 'hotdog', {}]

NOTE: filter() does NOT mutate the original array

map(callback[, arg])

Creates/returns a new array with all returned values from callback function

Your callback function takes 3 params:

  • element - the current element being iterated over
  • index - the current index of the element in the Array
  • array - the array itself being traversed
function tripleIt(element, index, array) {
    return element * 3;
}

var myArray = [3, 12, 1, 9];

myArray.map(tripleIt); //return [9, 36, 3, 27]

console.log(myArray) //[3, 12, 1, 9]

var myOtherArray = [3, 12, 1, 'taco'];

myOtherArray.map(tripleIt); //return [9, 36, 3, NaN]

console.log(myArray) //[3, 12, 1, 'taco']

NOTE: map() does NOT mutate the original array

reduce(callback[, initalValue])

Returns a single value accumulated against all values from callback function

Your callback function takes 4 params and 1 optional param:

  • previousValue - the previous element being iterated over
  • currentValue - the current element being iterated over
  • index - the current index of the array
  • array - the array itself being traversed
function summarize(previousValue, currentValue, index, array) {
    return previousValue + currentValue;
}

var myArray = [3, 12, 1, 9];

myArray.reduce(summarize); //return 25

console.log(myArray) //[3, 12, 1, 9]

//Start at a certain initial value
myArray.reduce(summarize, 10); //return 35

console.log(myArray) //[3, 12, 1, 9]

NOTE: reduce() does NOT mutate the original array

If you pass NO optional param, first iteration is at index 1 so that previous/next have values

//Omit index and array is still valid

function summarize(previousValue, currentValue) {
    return previousValue + currentValue;
}

var myArray = [3, 12, 1, 9];

myArray.reduce(summarize); //return 25

console.log(myArray) //[3, 12, 1, 9]

//Start at a certain initial value
myArray.reduce(summarize, 10); //return 35

console.log(myArray) //[3, 12, 1, 9]

reduceRight(callback[, initalValue])

Returns a single value accumulated against all values from callback function

Your callback function takes 4 params and 1 optional param:

  • previousValue - the previous element being iterated over
  • currentValue - the current element being iterated over
  • index - the current index of the array
  • array - the array itself being traversed

NOTE: reduceRight() does NOT mutate the original array

reduceRight() has the same functionality as reduce() except that it starts from the right side of the input array

References

Making Arrays More Functional

By Joe Karlsson

Making Arrays More Functional

  • 2,008