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