Sample Video Frame
26: Transforming Data
Functional Programming in JavaScript is limited mostly to using "data transforms" and callbacks. As you learned in Exercise 25 you can't really do recursion, but you can use functions to change data easily. What you can do reliably is transform data using four functions:
map
-- Apply a calculation on each element.reduce
-- Turn a sequence into a final calculation.find
-- Search for an element in a sequence.filter
-- Filter out selected elements from a sequence.forEach
-- Just loop over a sequence without a result.
I'm using the word "sequence" since these functions should be on most anything that works like an Array
...maybe...if they did it right. Let's look at each one:
map
Calling .map
on a sequence will produce a new sequence with a change to each value based on the result of a callback:
> let x = [1,2,3,4];
> x.map((i) => i + 10);
[ 11, 12, 13, 14 ]
>
You can see I passed a callback to .map
that simply added 10 to the numbers in x
and produces a new Array
with [11, 12, 13, 14]
. Remember that in simple callbacks like this you don't need return
since the result will be returned by default.
reduce
With reduce
you are building a calculation based on each element of the sequence, and you use an "accumulator" to build the result:
> let x = [1,2,3,4];
> x.reduce((acc, i) => acc *= i);
24
>
You can see that you receive the accumulator as acc
and it starts with the first element. You then perform your calculation with acc
, and return the result, which is carried on to the next iteration. When you're done, reduce
returns acc
(which is 24).
find
The find
function will go through your Array
and stop when it finds the first element that returns true
:
> let x = [0, 1,2,3,4];
> x.find((i) => i == 3);
3
> x.find((i) => i);
1
Remember that JavaScript's concept of "true" is very loose so I show you how I find 3 using ==
, but also that I find 1 by just returning i
. Since the first "truthy" value is 1 that's why it works.
filter
You use filter
to pull out all the elements that match a true
return value:
> let x = [1,2,3,4];
> x.filter((i) => i % 2 == 0);
[ 2, 4 ]
>
In this example I pull out a new Array
with only the even numbers by using %
on each element.
forEach
The final operation you can use is forEach
, which is like map
but doesn't produce a new sequence when it's done. You typically use forEach
to do a final processing on the results, but you can also just use for-of
like normal.
Code
The final code for this exercise is an example of searching through an Array
of objects to calculate new nonsense.
let pets = [
{name: 'Yeller', type: 'Dog', age: 12},
{name: 'Akumano', type: 'Japanese Bobtail Cat', age: 2},
{name: 'Meaw Peesard', type: 'Siamese Cat', age: 100},
{name: 'James', type: 'Gecko', age: 2},
]
let ages_only = pets.map(pet => pet.age);
let total_age = ages_only.reduce((acc, age) => acc += age);
let meaw = pets.find(pet => pet.name == 'Meaw Peesard');
let old_animals = pets.filter(pet => pet.age > 10);
let young_animals = pets.filter(pet => pet.age <= 10);
console.log("Animal Ages:", ages_only);
console.log("Total Age:", total_age);
console.log("Meaw is:", meaw.age);
console.log("\nOld Animals:");
old_animals.forEach(pet => {
console.log(`\t${pet.name} is a ${pet.age} old ${pet.type}.`);
});
console.log("\nYoung Animals:");
for(let pet of young_animals) {
console.log(`\t${pet.name} is a ${pet.age} old ${pet.type}.`);
}
What You Should See
Running this code shows you the results of the calculations, but you could also try each one in the node shell.
$ node "code.js"
Animal Ages: [ 12, 2, 100, 2 ]
Total Age: 116
Meaw is: 100
Old Animals:
Yeller is a 12 old Dog.
Meaw Peesard is a 100 old Siamese Cat.
Young Animals:
Akumano is a 2 old Japanese Bobtail Cat.
James is a 2 old Gecko.
Learn JavaScript Today
Register today for the Early Access course and get the all currently available videos and lessons, plus all future modules for no extra charge.
Still Not Sure? Try the next FREE Lesson!