Home » /Home

Map: Another Higher Order Function

Map is another higher order function that goes through an array and doesn’t discard it but instead transforms/mutates it.

Here, I’d like to get an array of all the names of the animals.

const animals = []
  { name: ‘Catticus Finch’,  species: ‘cat’ },
  { name: ‘Peaches’,         species: ‘fish’ },
  { name: ‘Bobby’,           species: ‘dog’ },
  { name: ‘Lucifer’,         species: ‘cat’ },
  { name: ‘Beatrix’,         species: ‘rabbit’ },
  { name: ‘Cerulean’,        species: ‘fish’ }
];

Here’s how we would accomplish this with a for loop:

var names = [];

for (var i = 0; i < animals.length i+) {
  names.push(animals[i].name); 
}

The function .filter expects a boolean, but .map expects a callback function to return a transformed object it will push into a new array.

To return the names of each of the animals in code:

In ES5:

var names = animals.map(function() {
  return animal.name;
});

In ES6:

const names = animals.map(animal) => animal.name );

You can use .map to return a subset of an array. Since it expects a callback to return an object, we can make new objects.

In ES5

var names = animals.map(function(animal) {
  return animal.name + ‘ is a ‘ + animal.species;
});

In ES6

const names = animals.map(animal) => animal.name + ‘is a ‘ + animal.species );

Easier Array Manipulation with Higher Order Functions

.map() and .filter() are just a couple of higher order functions you can use to manipulate and iterate over arrays.

You can check out this link for further reading.

Mission DRY: Accomplished

When working with multiple levels of conditionals, it helps to DRY things up a bit: not repeating yourself can give performance gains as well as make your code more readable and elegant.

Here is one of the monstrosities I had before:

if (currentIcon === "clear-day")   {
  $("body").css("background-image", "url(https://i.imgur.com/voece1h.jpg)");
  }   else if (currentIcon === "partly-cloudy-night")   {
  $("body").css("background-image", "url(https://i.imgur.com/r8haFIj.jpg)");
  }   else if (currentIcon === "clear-night")   {
  $("body").css("background-image", "url(https://i.imgur.com/K6Bazrl.jpg)");
  }   else if (currentIcon === "partly-cloudy-day").  {
  $("body").css("background-image", "url(https://i.imgur.com/dUS9u9b.jpg)");
  }   else if (currentIcon === "cloudy")   {
  $("body").css("background-image", "url(https://i.imgur.com/Kx3ku27.jpg)");
  }   else if (currentIcon === "rain")   {
  $("body").css("background-image", "url(https://i.imgur.com/g4afvja.jpg)");
  }   else if (currentIcon === sleet)   {
  $("body").css("background-image", "url(https://i.imgur.com/pjq3VPO.jpg)");
  }   else if (currentIcon === snow)   {
  $("body").css("background-image", "url(https://i.imgur.com/vH9cyKD.jpg)");
  }   else if (currentIcon === wind)   {
  $("body").css("background-image", "url(https://i.imgur.com/ZtSl66b.jpg)");
  }   else if (currentIcon === fog)   {
  $("body").css("background-image", "url(https://i.imgur.com/5z0CXkZ.jpg)");
}

Really gross, right?

Consulting LinkedIn and Slack proved to be fruitful.

Changing if/else Chains Into Map Objects

A hash map is an object that you can iterate over like an array. The definition of a Map object can be found on the MDN.

Adam Recvlohe, a fellow freeCodeCamp Camper on LinkedIn recommended I use a Map for changing the background of my freeCodeCamp Weather App dynamically. He showed me some code and I eventually settled on this:

const iconMap = {
  "clear-day": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/sunny.jpg)",
  "partly-cloudy-night": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/fineas-anton-136459+copy.jpg)",
  "clear-night": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/sam-mcjunkin-38078.jpg)",
  "partly-cloudy-day": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/jeff-nafura-294909.jpg)",
 "cloudy": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/jonatan-pie-260835.jpg)",
 "rain": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/3opt\_rain.jpeg)",
 "sleet": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/jonatan-pie-190398.jpg)",
 "snow": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/snow.jpg)",
 "wind": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/jon-flobrant-2845.jpg)",
 "fog": "url(https://s3.us-east-2.amazonaws.com/weatherappfcc/elaine-li-416.jpg)"
};

(function() {
  $("body").css("background-image", iconMap[currentIcon]);
})();

Here, we take a Map object and use an anonymous function calls the .css jQuery method on the body which will change the background image by injecting that css into the body. Also as an argument to the css method is an iteration over the iconMap Map object that maps each image to the currently displayed Skycon.

Next: Cleaning Up The if/else Mess of an Icon Display

Up above you probably observed my conditional hell. It was the same for the icons where I called the jQuery show()/hide() methods in if/else statements for every. Icon. Pure insanity.

I went to the Code Newbie Slack and asked Joseph Rex for help as he has been guiding me through a few of the Express and other JavaScript problems I have been having. After some bugs and error handling we came up with a nifty ES6 solution that is much cleaner, using Template Literals to clean up the constant calls to each icon.

// Write a function that takes two parameters
let iconDisplay = (iconName, current) => {
   //Assign a template literal to a constant that will
//represent each icon
   const jqObj = $(`#${iconName}`);
   // Use the ternary operator to determine with the //iconName is the current icon being shown for the condition
//and based on that, show or hide the appropriate icon
   iconName === current ? jqObj.show() : jqObj.hide();
};

 // call the function and compare it to the Skycon for each 
 // Weather condition.
 iconDisplay("clear-day", currentIcon);
 iconDisplay("clear-night", currentIcon);
 iconDisplay("partly-cloudy-day", currentIcon);
 iconDisplay("partly-cloudy-night", currentIcon);
 iconDisplay("cloudy", currentIcon);
 iconDisplay("fog", currentIcon);
 iconDisplay("rain", currentIcon);
 iconDisplay("sleet", currentIcon);
 iconDisplay("snow", currentIcon);
 iconDisplay("wind", currentIcon);

Pretty cool.

Learning Express with The Web Developer Bootcamp

Pretty soon I’ll be diving deep into how much I am learning about Express with The Web Developer Bootcamp. To get a sense of where I was a couple days ago, read this.