Bootcamp Notes – Day 2 (Tues) – React: Advanced Array Methods
Advanced Array Methods
Over of Advanced Array Methods
An array is a data structure that can be stored with a variable. It is a special kind of object that follows some, but not all of the rules of an object. Arrays have many predefined methods that work on any array. For example, an array method called SORT. A method is a function that’s never called by itself and it’s always called using dot notation on some kind of data such as an array.
To call both functions and methods, you must include a parameter list in closing (parens), even if it’s empty like with sort.
Now onto with Advanced Array Methods.
It is possible to pass a function into another function as an argument. It is actually possible to pass a function into another function’s parameter list as an argument. There’s a pair of concepts in programming called higher order functions and callback functions.
Higher Order Functions – A function that takes another function as an argument, or returns a function as a return value. Basically it’s a function that’s written in a way that it uses another function.
Callback Functions – A function that’s passed into a higher order function as an argument, then used inside it (called back). A callback function is the flip side of that. It’s a function that’s passed into a higher order function as an argument than used inside it.
Array Methods: Map, Filter, Reduce are higher order functions, each take a callback function as an argument. The callback function is defined by the programmer and is usually in the form of an arrow function. None of these methods are mutator methods. They do not change the original array. They can be classified as iteration methods – they iterate through the array as many times as the array length. Map, Filter, Reduce all have return values. Not all array methods do. Map and filter both return a new array. Reduce returns a single value, not an array.
Advanced Array Methods: Map
Map iterates through an array and performs a given callback function on every item in the array. You can think of it as similar to a for loop. For example, let’s say you wanted to go through an array of numbers and create a new array with those numbers doubled.
- You can see how the map method also arrived at the same goal, but in a concise and elegant way.
- As its argument, it took an arrow function as its callback function (n => n * 2) which doubled every item in arr1 and returned the doubled value as an item in arr4.
- The variable name n is arbitrary and was chosen here to stand for number.
- The map method will iterate on each element of the array on which it was called (in this case, arr1) and assign the value of the n to the current item in the array, perform the callback function (n * 2) then return the changed value to the new array arr4.
- The map method will always return a new array that is the same size as the array on which it was called, and it will never change the array on which it was called – it is not a mutator method.
Advanced Array Methods: Filter
FILTER takes a callback function that specifies a filtering condition, iterates through an array, and returns a new, filtered array. The array method filter takes an array and a callback function that specifies a filtering condition, iterates through the array, and returns a new array that contains only the items that passed through the filter.
Look at this example below:
- You can see that arr1 still contains the old array, and arr2 now contains the new array, which is all the numbers from arr1 that are less than 7.
- Like map, filter will iterate through every item in the array on which it was called, in this case, arr1.
- At each iteration, it will assign that item to the value of the first parameter in a callback function, then check the filtering condition inside the function body, in this case, n < 7.
- If the result is true, then it will place that item inside a new array. If the result is false, it will not.
- At the end, when it has iterated through every item in the array on which it was called, it will return a new array composed of the items that passed the filtering condition.
- This is a major difference from the map method, which always returns an array that is of the same size as the original array.
- Filter does not always return an array of the same size (though it can, if all items pass the filtering condition).
Another example:
You should be able to see that the resulting filteredAnimals array includes all the items except ‘bear’. If you checked the value of the animals array at this point, it would be the same as it started with. Filter is also a non-mutator method. It creates a new array, but does not change the old array.
Note: method filter, which like map, takes a callback function and returns a new array without mutating the original array. Now unlike map, however, filter does not always return an array of the same size as the original.
Advanced Array Methods: Reduce
Of these three Map, Filter, Reduce. Reduce is probably the most difficult to understand right away.
Let’s start with differences between reduce and map and filter.
Map and Filter both return a new array.
Map returns a new array of the same length as the old array, but will typically change the array item’s values.
Filter will return a new array, and the length (number of items) in the array may be changed, but the values of the filtered array items will not change.
Reduce will not return an array at all. Instead, it will return a single value.
With the reduce method, we need to pass in two values to its callback. We will name them A and C for this example below. That stands for (A) accumulator and (C) current value. These names a and c are not required. Just using them for our example.
C holds the value of the current array item. The accumulated variable’s value gets updated at each iteration, then eventually at the very end of all the iterations, it becomes the return value for the entire reduce method.
There is an optional third value that could have been used here to set the initial value of the accumulator, but we have not used it in this example.
When an initial value is not set with that optional third value, then at the first iteration, the accumulator is set to be equal to the first value in the array, and currentValue is set to be equal to the second.
Think of (a) the accumulator as a running total!
Also, please note: That while we did not need to set an initial value for using reduce on an array of numbers. It’s a different story when it comes to using reduce on a array of objects. So, when working with arrays of objects, you will need to set an initial value for reduce!
Remember: reduce method has a couple of key differences from the map and filter methods — it returns a single value instead of an new array, and it requires two parameters instead of one. It is also similar to the map and filter methods in that it iterates through an array and applies a callback function to each item in the array, and it does not mutate the original array.
Arrays of Objects
So far you have been using advanced array methods on arrays of primitive types such as number and strings. We will now take a look at working with arrays of objects.
So far, you have been used to seeing objects stored as variables, like this:
const dessert1 = {
type: "cake",
flavor: "chocolate",
cost: 4.50
}
const dessert2 = {
type: "pie",
flavor: "pumpkin",
cost: 3.75
}
const dessert3 = {
type: "donut",
flavor: "chocolate",
cost: 1.50
}
Now we go to this, array with objects:
const desserts = [
{
id: 0,
type: "cake",
flavor: "chocolate",
cost: 4.50
},
{
id: 1,
type: "pie",
flavor: "pumpkin",
cost: 3.75
},
{
id: 2,
type: "donut",
flavor: "chocolate",
cost: 1.50
}
];
It’s common practice to give each object in an array of objects a unique ID as one of its properties. That way, even if the order of the array gets moved around somehow (for example, by a shift() or unshift() method being applied to it), each object still has a unique identifier that stays constant.
Filter example: for chocolate-flavored dessert items
You can see value only having chocolate flavored deserts.
Reduce example:
For our example again, we can use reduce to total up the cost of every desert in this array.
When no initial value is set, then at the first iteration, reduce will use the first item in the array for the accumulator value (total) and the second item in the array for the current value (dessert). That is fine if we are working with primitive values but in this case, we’re working with objects and we don’t want to se the accumulator value total to the first item which is the entire object because that is not a number. That would mean that we are trying to add this entire object to the cost of the second item.
Method Chaining
Method Chaining means running multiple methods in a single statement by use of return values.
Let us look at array methods first: map, filter, reduce.
Methods must have return values in order to be chained: map, filter, reduce all do!
Remember, Map and Filter return new arrays. Reduce returns a single value.
Method Chaining – Array methods with built-in return values
For our example below:
- Let’s say we want to create a new array where we filter out only the states that begin with the letter M:
- Check that the mStates variable contains an array with just Montana and Maine.
- We can go through and change every state name in this new array to being all upper case using a map method on the mStates variable:
- However, we can also do the exact same thing as we did in two steps above but using a single step, with the help of method chaining:
- You see that a dot was added at the end of the filter method, then the map method was chained to it, treating the entire filter method call as if it were the new array for map to work on.
- We could chain another method to the end of the map method. There is no limit to how many times yo can chain to a method, aside from readability and maintainability concerns. Try this example:
- In the above example, we filtered out the states starting with the letter “M”, changed all the letters to upper case, then added an exclamation point to the end of every state name. Check the content of the evenMoreChaining variable to see the result.
Method chaining with custom object methods and adding return values
With custom objects that you create, it’s up to you whether or not to provide their methods with return values, but they are required if you wish to chain other methods to them.
We can make the bird sing and make it fly, but we cannot do both with a chain, because neither the sing() nor fly() methods have been set with return values. Remember, methods are really functions that are bound to the object, and like all functions, if they are not given a return value, they return undefined. In this case, the return value that we want to have is the bird object itself, because the fly() method is defined on the bird object. Again, the this keyword comes to our rescue, since inside the object, this refers to the object itself. That means we can return this from each method.
Remember this: You can chain methods together as long as there is a valid return value from the method you are chaining TO.
Also some build-in methods already have built-in return values (such as map, filter, reduce)
When you write your own custom methods, you must return the value yourself.
Additional Resources:
- Parameters and Arguments
- Eloquent JavaScript – Higher-Order Functions
- MDN – Callback function
- Medium.com article – First class functions, higher order functions & callback functions
- W3Schools – JavaScript Array map() Method
- JavaScript.info – Array methods – map
- MDN – Map
- W3Schools – JavaScript Array filter() Method
- JavaScript.info – Array methods – filter
- MDN – Filter
- W3Schools – JavaScript Array reduce() Method
- JavaScript.info – Array methods – reduce
- MDN – Reduce
- MDN – Reduce (see Example on “Sum of values in an object array”)
- Eloquent JavaScript – Data Structures – Objects and Arrays
- Medium.com article – Understanding Method Chaining
More Resources:
Books
You Don’t Know JavaScript (YDKJS) – Written by an excellent JavaScript programmer, Kyle Simpson (aka @getify), this first edition of YDKJS is a free resource that describes every aspect of modern JavaScript is a pragmatic and approachable way. (If you find this resource valuable, consider purchasing the content to support the author. The second edition is available as a paid version.)
Some relevant sections of YDKJS are:
Another excellent resource to learn the JavaScript programming language is Eloquent JavaScript (EJ). EJ is also a free resource that the author graciously provides and maintains.
Although a little buried, a relevant section of EJ is:
Online Articles
Overview of ES5 vs ES6
https://codeburst.io/es5-vs-es6-with-example-code-9901fa0136fc
Var, Let, Const
https://hackernoon.com/js-var-let-or-const-67e51dbb716f
More on Functions
https://codeburst.io/javascript-functions-understanding-the-basics-207dbf42ed99
More on Arrow Functions
https://codeburst.io/javascript-arrow-functions-for-beginners-926947fc0cdc
https://www.sitepoint.com/es6-arrow-functions-new-fat-concise-syntax-javascript/
Scope and ‘This’
https://javascriptplayground.com/javascript-variable-scope-this/
Arrow Functions & Lexical ‘This’
https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4
More on Map, Reduce, Filter
https://medium.com/poka-techblog/simplify-your-javascript-use-map-reduce-and-filter-bd02c593cc2d
https://codeburst.io/learn-understand-javascripts-reduce-function-b2b0406efbdc
Function Scope & Block Scope
https://edgecoders.com/function-scopes-and-block-scopes-in-javascript-25bbd7f293d7
Callback Functions
https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced
Function Declarations vs Function Expressions (& Hoisting)
https://medium.com/@mandeep1012/function-declarations-vs-function-expressions-b43646042052
Objects
https://codeburst.io/various-ways-to-create-javascript-object-9563c6887a47
Value vs. Reference
https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
Spread Operator & Rest Parameters
https://javascript.info/rest-parameters-spread-operator