Higher Order Functions Review
Explaining Each
Expanding Each
Loops on Loops on Loops
Takes a function as an argument.
Returns a function to be used at a later time.
This week we are focused on the first one.
var each = function(collection, callback){
// loops through the collection
for (var i = 0; i < collection.length; i++){
// passes each element inside of collection
// to the callback
callback(collection[i])
}
};
var each = function(collection, callback){
for (var i = 0; i < collection.length; i++){
// passing each array element into our callback
callback(collection[i]);
}
}
var bestSentence = ['I', 'love', 'javascript'];
each(bestSentence, function(word){
console.log(word.toUpperCase());
});
// 'I'
// 'LOVE'
// 'JAVASCRIPT'
The anonymous function corresponds to the callback parameter we specify in each.
The `word` parameter corresponds with the argument being passed into our callback.
var each = function(collection, callback){
for(var i = 0; i < collection.length; i++){
callback(collection[i]);
}
}
var numbers = [1, 2, 3, 4, 5];
each(numbers, function(element){
// returning instead of console.logging
return element;
});
var each = function(collection, callback){
for(var i = 0; i < collection.length; i++){
console.log(callback(collection[i]));
}
}
var numbers = [1, 2, 3, 4, 5];
each(numbers, function(element){
// returning instead of console.logging
return element;
});
Let's throw a console.log inside of our `each` so that we can see what's being returned.
Definition: The Each function provides its callback access to each element inside of a collection.
That's it.
No really, that's it.
multBy2 takes an array of numbers and returns a new array with each element multiplied by 2
var multBy2 = function(array) {
var results = [];
for (var i = 0; i < array.length; i++){
results.push(array[i] * 2);
}
return results;
};
Let's replace our for-loop with our 'each' function
var multBy2 = function(numbers) {
var results = [];
each(numbers, function(number){
results.push(number * 2);
});
return results;
};
Our `ea` function makes this code more expressive and clean.
multBy2 in depth:
var multBy2 = function(numbers) {
var results = [];
each(numbers, function(number){
results.push(number * 2);
});
return results;
};
The callback has access to the `results` array in its parent scope
Thanks to each, the callback also has access to each number in the `numbers` array.
multBy2 in action:
var multBy2 = function(numbers) {
var results = [];
each(numbers, function(number){
results.push(number * 2);
});
return results;
};
var nums = [1, 2, 3, 4, 5];
var numsMult2 = multBy2(nums);
Let's throw this in the console and see what we get.
var each = function(collection, callback){
for (var i = 0; i < collection.length; i++){
callback(collection[i]);
}
};
We've been building functions where loop can only take an array, but what about objects?
var each = function(collection, callback){
if (Array.isArray(collection){
for (var i = 0; i < collection.length; i++){
callback(collection[i]);
}
} else if (typeof collection === 'object'){
for (var key in collection){
callback(collection[key]);
}
}
};
var obj = {name: 'Albrey', favoriteColor: 'blue'};
each(obj, function(value){
console.log(value);
});
// 'Albrey', 'blue'
var obj = {name: 'Albrey', favoriteColor: 'blue'};
each(obj, function(value){
console.log(value);
});
// 'Albrey', 'blue'
When do we ever just deal with values?
Let's expand our loop even further to support passing keys/indexes to our callback.
var each = function(collection, callback){
if (Array.isArray(collection)){
for (var i = 0; i < collection.length; i++){
callback(collection[i]);
}
} else if (typeof collection === 'object'){
for (var key in collection){
callback(collection[key]);
}
}
};
Passing the current key/index to our callback.
var each = function(collection, callback){
if (Array.isArray(collection)){
for (var i = 0; i < collection.length; i++){
callback(collection[i], i);
}
} else if (typeof collection === 'object'){
for (var key in collection){
callback(collection[key], key);
}
}
};
var obj = {name: 'Albrey', favoriteColor: 'blue'};
each(obj, function(value, key){
console.log('this is the value:', value);
console.log('this is the key:', key);
});
// "this is the value: Albrey"
// "this is the key: name"
// "this is the value: blue"
// "this is the key: favoriteColor"
Specifying `key` parameter in our callback.
var obj = {name: 'Albrey', favoriteColor: 'blue'};
each(obj, function(key){
console.log('we only want the key', key);
});
// "we only want the key: Albrey"
// "we only want the key: blue"
We must insert 2 parameters in order to access the key.
var obj = {name: 'Albrey', favoriteColor: 'blue'};
each(obj, function(value, key){
console.log('we only want the key', key);
});
// "we only want the key: name"
// "we only want the key: favoriteColor"
var person = {
name: "Jon Tippens",
greatestFear: "Those frozen biscuit things.",
dateUsedAgainstHim: "2/02/1997",
};
for (var characteristic in person){
console.log(person[characteristic]);
};
// 'Jon Tippens'
// "Those frozen biscuit things."
// "2/02/1997"
This data structure is not nested in another datastructure
var people = [{
name: "Jon Tippens",
greatestFear: "Those frozen biscuit things.",
dateUsedAgainstHim: "2/02/1997",
}, {
name: "Albrey Brown",
greatestFear: "Brain aneurysm.",
dateUsedAgainstHim: "03/30/1991",
}];
Our original person object is nested in the 'people' array
var jon = {
name: "Jon Tippens",
greatestFear: "Those frozen biscuit things.",
dateUsedAgainstHim: "2/02/1997",
};
var albrey = {
name: "Albrey Brown",
greatestFear: "Brain aneurysm.",
dateUsedAgainstHim: "03/30/1991",
};
var people = [jon, albrey]
Let's make this look more palatable
Our two persons are nested in our people array.
How do we loop through each object?
var people = [jon, albrey]
for (var i = 0; i < people.length; i++){
console.log(people[i]);
};
// { name: "Jon Tippens", greatestF...}
// { name: "Albrey Brown", greatestF...}
Looping through the `people` array allows us access to each `person`.
We need a second for-loop to loop through the characteristics in our persons
Add another for loop
var people = [jon, albrey]
for (var i = 0; i < people.length; i++){
var person = people[i];
for(var characteristic in person){
console.log(person[characteristic]);
}
}
// Jon Tippens
// Those frozen biscuit thingies
// 2/02/1997
// Albrey Brown
// Brain aneurysm
// 03/30/1991
instead of `person`, we can access people[i]
var people = [jon, albrey]
for (var i = 0; i < people.length; i++){
for(var characteristic in people[i]){
console.log(person[characteristic]);
}
}
// Jon Tippens
// Those frozen biscuit thingies
// 2/02/1997
// Albrey Brown
// Brain aneurysm
// 03/30/1991
var people = [jon, albrey]
for (var i = 0; i < people.length; i++){
for(var characteristic in person){
console.log(person[characteristic];
}
}
Remember, we're supposed to be ridding the world of for-loops
How can we use our `loop function to achieve the same thing?
var people = [jon, albrey]
// loop through the people array
loop(people, function(person){;
for(var characteristic in person){
console.log(person[characteristic]);
}
});
var people = [jon, albrey]
// loop through the people array
loop(people, function(person){;
loop(person, function(characteristic){
console.log(characteristic);
});
});
// Jon Tippens
// Those frozen biscuit thingies
// 2/02/1997
// Albrey Brown
// Brain aneurysm
// 03/30/1991
First, let's replace our first for-loop with a `loop`
Then, we can replace our for-in loop with a `loop` function
var people = [jon, albrey]
loop(people, function(person){;
console.log(person)
});
// { name: "Jon Tippens", greatestF...}
// { name: "Albrey Brown", greatestF...}
Looping through the `people` array allows us access to each `person`.
var people = [jon, albrey]
// loop through the people array
loop(people, function(person){;
loop(person, function(characteristic){
console.log(characteristic);
});
});
// Jon Tippens
// Those frozen biscuit thingies
// 2/02/1997
// Albrey Brown
// Brain aneurysm
// 03/30/1991
We can then pass each `person` to our loop, and console.log
var people = [jon, albrey]
for (var i = 0; i < people.length; i++){
for(var characteristic in person){
console.log(person[characteristic];
}
}
Remember, we're supposed to be ridding the world of for-loops
How can we use our `loop function to achieve the same thing?
var people = [jon, albrey]
// loop through the people array
loop(people, function(person){;
for(var characteristic in person){
console.log(person[characteristic]);
}
});
var people = [jon, albrey]
// loop through the people array
loop(people, function(person){;
loop(person, function(characteristic){
console.log(characteristic);
});
});
// Jon Tippens
// Those frozen biscuit thingies
// 2/02/1997
// Albrey Brown
// Brain aneurysm
// 03/30/1991
First, let's replace our first for-loop with a `loop`
Then, we can replace our for-in loop with a `loop` function