Learn map(), filter(), reduce(), and sort() in JavaScript

Welcome to Day 3 of the JavaScript30 challenge, and today we’re going to checkout some of the most advanced and important array methods in JavaScript.

If you want to know more about JavaScript30, watch the video below and go here

Unlike the last 3 days, today we don’t have an actual project to work on but we do have 8 interesting sets of problems, which we’ll solve using the following array methods –

filter()
    map()
    sort()
    reduce()

These methods are surely one of the most important and also one of the most confusing concepts, I had difficulty understanding each of them.

But if you’re serious about learning JavaScript, then you can’t escape from them, as they are also commonly used in libraries like React, etc.

Array Methods

If you are confused about what the array method itself is in the first place,

You can think of them as certain operators used to perform certain operations on individual items of an array, you’ll learn more about them as soon as we advance in this article.

So enough talk, let’s just jump on the problem now.

Starter Files

const inventors = [
    { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
    { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
    { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
    { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
    { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
    { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
    { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
    { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
    { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
    { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
    { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
    { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];

const people = [
  'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',
  'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',
  'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',
  'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',
  'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'
];

Well, in the name of starter files today, we only have 2 sets of arrays on which we’ll use our methods, so make sure to copy them and set up your system to get started.

Question 1

// Array.prototype.filter()
// 1. Filter the list of inventors for those who were born in the 1800's

.filter()

.filter() creates an array filled with all array elements that pass a test which is provided in the form of a function inside the the filter() method.

Solution

const fifteen = inventors.filter((inventor) => {
    if(inventor.year >= 1800 && inventor.passed < 1900) {
        return inventor
    }
})
console.table(fifteen)

Explanation

  1. We passed filter() method on inventors array and stored it inside a variable called fifteen.
  2. Next step is write a if statement to return those individual inventors who were born before 1800 and passed before 1900.
  3. And at last do a console.table(fifteen) to create a nice table of returned array elements inside your console.

Question 2

// Array.prototype.map()
// 2. Give us an array of the inventors first and last names

.map()

.map() method creates a new array with the result of calling a function for every array element individually. In simple words, you provide .map() an array and a custom function which you wrote, now the .map() will call the function on every single element.

Let’s look at an example to understand it better.

const numbers = [4, 9, 16, 25];
const newArr = numbers.map((num) => {
  return num*2;
})
console.log(newArr) // result = [8, 18, 32, 50]

Notice how we passed an arrow function with a return statement of num*2, and this statement returned a new list of array where each element is double of the previous value.

Solution

const fullName = inventors.map((inventor) =>{
    return `${inventor.first} ${inventor.last}`
})
console.table(fullName)

Explanation

  1. We created a variable called fullName and stored the mapped value of investors array.
  2. Inside the .map() method, we returned the ${inventor.first} ${inventor.last} which is just a template literal used with dot notation to access first and last name of inventors.
  3. And at last, we do a console.table(fullName) to display the following data on the console.

Question 3

// Array.prototype.sort()
// 3. Sort the inventors by birthdate, oldest to youngest

.sort()

.sort() method is used to sort the elements inside an array. By default, it sorts the values as strings.

Solution

const ordered = inventors.sort((firstPerson, secondPerson) => {
    if(firstPerson.year > secondPerson.year){
        return 1
    }
    else{
        return -1 
    }
})
console.table(ordered)

Explanation

  1. We stored the results of our sort() method inside and variable called ordered.
  2. We passed a function with 2 parameters, 1st firstPerson and 2nd secondPerson.
  3. Inside the function , there is an if statement which checks whether the firstPerson is older than the secondPerson or not, if yes return 1, if no return -1.
  4. Value of 1 ranks firstPerson before secondPerson and vice-versa.

Question 4

// Array.prototype.reduce()
// 4. How many years did all the inventors live?

.reduce()

The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value. Let’s understand this with an example –

const array1 = [1, 2, 3, 4];
const reducer = array1.reduce((accumulator, currentValue) => return accumulator + currentValue;)
console.log(reducer) // 1 + 2 + 3 + 4 = 10

accumulator is the accumulated value from previous returns and currentValue as the name same says is currentValue,

On each iteration currentValue is added to the accumulator making it the accumulation of all the values which array holds, it’s a safe bet to give a initial value of 0 to the reduce function for it to always invoke the call function from index 0.

Solution

const totalYears = inventors.reduce((total, inventor) => {
      return total + (inventor.passed - inventor.year);
    }, 0);

    console.log(totalYears);

Explanation

  1. We stored our .reduce() inside a variable called totalYears.
  2. We initialized an accumulator value in the name of total and a currentValue determined by the passing year – Birth date, thus determining the total age of the inventor.
  3. On each iteration, this current value is being added to our total parameter, thus calculating the cumulative age of all our inventors at last.

Question 5

// 5. Sort the inventors by years lived

Solution

const age  = inventors.sort((firstPerson, secondPerson) => {
    const lastGuy = (firstPerson.passed - firstPerson.year)
    const nextGuy = (secondPerson.passed - secondPerson.year)

    if(lastGuy > nextGuy) {
        return 1
    }
    else {
        return -1
    }
})
console.table(age)

Explanation

  1. We stored our sort() method inside a variable called age.
  2. We gave 2 arguments, firstPerson and secondPerson.
  3. We stored the age of firstPerson and secondPerson inside another variables called lastGuy and nextGuy.
  4. We wrote an if statement to determine which one is older.
  5. And finally console.table() the age variable.

Question 6

6. Create a list of Boulevards in Paris that contain 'de' anywhere in the name
// https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris

Screenshot of "Boulevards in Paris" Wikipedia page

First we’ll use our debugger and know what common class are these link sharing.

And we found that these individual links are stored inside a parent div with class of ‘mw-category’.

So we’ll target this class and extract all the links from same

const category = document.querySelector('.mw-category')
const links = [...category.querySelectorAll('a')]
console.log(links)

So, we stored the parent element of all the links inside a variable called category, and then created an array of individual links with help of spread operator and querySelectorAll, and look below what we’ve got

const de = links
                 .map(link => link.textContent)
                 .filter(streetName => streetName.includes('de'))
  1. Next we created a variable called de and stored the result of mapped and filtered list in it.
  2. We used .map() to create an array of text of links with the help of .textContent
  3. And then we used a .filter() to pass only those array elements which contains the word ‘de’.

Question 7

// 7. sort Exercise
// Sort the people alphabetically by last name

Solution

const sorted = people.sort((lastOne, nextOne) => {
    const [aLast, aFirst] = lastOne.split(', ')
    const [bLast, bFirst] = nextOne.split(', ')

    return aLast > bLast ? 1 : -1
})
console.table(sorted)

Explanation

  1. We created a variable called sorted which stores the result of people.sort()
  2. We passed 2 arguments inside the function , i.e., lastOne and nextOne, broke it into two parts with the help of .split()
  3. These 2 parts are left and right side of ‘, ‘(comma and space) which are then stored inside their separate variables
  4. And then we’ll return the result of the comparison of aLast and bLast, if it passes return 1, if it fails return -1(we are using Ternary Operator here)
  5. And finally console.table(sorted)

Question 8

// 8. Reduce Exercise
// Sum up the instances of each of these

const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ];

// We have to count how many times each of these words appear in the array

Solution

const transportation = data.reduce((obj, item) => {
    if(!obj[item]) {
        obj[item] = 0
    }
    obj[item] += 1
    return obj
}, {})

console.table(transportation)

Explanation

  1. We created a variable called transportation and stored the value of data.reduce() in it.
  2. At the end of our .reduce(), we passed an initial value of an empty object {}, it will convert our obj parameter as an object and item parameter as its value.
  3. There is an if statement which initiates the obj with value as 0 on its first instance.
  4. Once the if statement is over or the related obj key was initiated previously, it will increase the its value by 1
  5. And at last, we do a console.table(transportation)

Bonus

I’ve used arrow functions, and ternary operator very commonly throughout the article, check out my Instagram post if you don’t know about them.

Conclusion

Congratulations, you’ve made it this far, if you’re stuck somewhere in the problems or have any question or confusion, comment below.

I’ll see you in another post.

Till then,

Happy Coding 🙂

27