Adventures in Javascript pt.1
Tags: composing, filters, maps, reduce
Published: 2017-09-24 18:29:50

---
title: "Adventures in Javascript pt.1"
published: true
tags: composing,filters,maps,reduce
canonical_url: 
---

I keep thinking about writing more, but the more I think about it, the less I do it. So today I stopped thinking and started&nbsp;writing.

It can only go downhill from&nbsp;here…

Mostly, I couldn’t think of anything to write about. Most things I know have been written about TO DEATH. But today, I realised: that’s ok! Everyone learns things differently (which is also ok, by the way), so it may be that somebody doesn’t understand something because it just hasn’t been demonstrated, or explained, in a way that suits their learning&nbsp;style.

As well as that, they say the best way to cement your learning of something is to write it down, or pass it on. Maybe this will help someone, even if that someone is just&nbsp;me!

![](https://cdn-images-1.medium.com/max/888/1*gj0PczAJKxzDtNf7aMrLFg.png)<figcaption>Some sort of adventure-type dude</figcaption>

This morning, I was thinking about compositional chaining of functions in Javascript — something we are doing more and more of at work as we move to a more functional style (yes, yes - I know it’s not REALLY functional programming, but it’s a step in the right direction. Note, I said STYLE. We’re not going full blown Haskell and twiddly moustaches just&nbsp;yet…).

Anyway, I thought I would put down my thoughts on the old favourites - map, filter and reduce. These took some brain-wrangling to get my head around. I read a lot, watched a lot of videos (thanks [Professor Frisby](https://egghead.io/courses/professor-frisby-introduces-composable-functional-javascript)), but it just wouldn’t stick. They aren’t difficult, but my brain just couldn’t deal with it, for whatever&nbsp;reason.

So, first up is&nbsp; **Map** :

Map can be called on an array, which then calls the function passed in to it on each item in the first&nbsp;array.

```
const addOne = num => num + 1;
let nums = [1,2,3,4,5,6,7,8,9];
let jsMap = nums.map(addOne); // [2, 3, 4, 5, 6, 7, 8, 9, 10]
```

You can paste this into your editor, or IDE and run with Node to see this for yourself (same with all of these examples).

It’s also useful to remember that this doesn’t have to be a function passed in (although, this will probably prove more beneficial in filter and&nbsp;reduce):

```
let nums = [1,2,3,4,5,6,7,8,9];

let jsMap = nums.map(num => num>= 5);
// [false, false, false, false, true, true, true, true, true]
```

The important thing about map is that **the original array is unmodified:**

```
const addOne = num => num + 1;
let nums = [1,2,3,4,5,6,7,8,9];
let jsMap = nums.map(addOne); // [2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(nums); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

It seems to me that this is on of the main bonus points of Functional Programming - **immutability**. Basically, this means that the original _thing_ remains unchanged. Not mutated. By radiation or any other&nbsp;thing.

![](https://cdn-images-1.medium.com/max/300/1*F4bhZugZLbxJtVcYXPknuw.png)<figcaption>Map. Innit.</figcaption>

So, back to my opening gambit- what is different about this explanation? I’m sure you’ve seen the addOne function written a trillion times if you’re trying to get your head around these “pure functions. Well, nothing. So&nbsp;far.

But now, I thought I would write a manual map function. Using good, old-fashioned JavaScript for loops (although, these are now pretty much the Devil). Everyone understands a forloop. If you don’t, I would go back to something more&nbsp;basic….

So, here goes (using our addOne function from earlier):

```
const map = (arr, func) => {
  let results = [];
  for(let i = 0; i < arr.length; i++) {
    let result = func(arr[i]);
    results.push(result);
  };

// Note that results is returned -
  // the original array that was passed in is non-radioactive

return results;
  }

let ourOwnVerySpecialMapResults = map(nums, addOne);
// [2, 3, 4, 5, 6, 7, 8, 9, 10]

// Nums is still unchanged
console.log(nums); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

A couple of things to note - the original nums array hasn’t become radioactive (or changed in any way). Where the addOne function is passed in to our map, only the name is passedwithout the function being called - that is done in the manual map we&nbsp;wrote.

But the main thing to take away from this is that **it is just a for&nbsp;loop!!**

Every result of the array value being passed to the function is pushed to a new array that is returned.

I guess the next question is: if it is this easy, why do we use the JS map? Well, we can easily chain other functions on to the end of our mapped result. More on that later. Part 2, maybe (if there is&nbsp;one)…

Next, **Filter:**

As with map, filter is really just another for loop in disguise. It walks through an array, checks each value and passes it to a new array if the value matches expectations. Like&nbsp;this:

```
let nums = [1,2,3,4,5,6,7,8,9];
let jsFilter = nums.filter(num => num > 5); // [6, 7, 8, 9]
```

So, it walks through nums, checks each value to see if it is greater than&nbsp;five:

`num => num > 5`

And returns it in the array if it is.&nbsp;Simples.

![](https://cdn-images-1.medium.com/max/300/1*-5TVKUIC9xGONGkqGYl5Zw.jpeg)<figcaption>Filter. Innit.</figcaption>

There we have it, a simple JS filter. As before, let’s write our&nbsp;own:

```
const moreThanFive = num => {
  if (num > 5) {
    return num;
  }
}

const filter = (arr, check) => {
  let results = [];
  for(let i = 0; i < arr.length; i++) {
    if (check(arr[i])) {
      results.push(arr[i]);
    }
  };
  return results; // nums is still non-mutant
};

let ourOwnVerySpecialFilterResults = filter(nums, moreThanFive);
// [6, 7, 8, 9]
```

As before, it is just a for loop, but with an if statement inside that controls what is pushed to the results&nbsp;array.

Is this making sense? Are you with me? I hope&nbsp;so…

Finally, **Reduce:**

So. Reduce takes two things: a function and a ‘3.5 inch floppy disk’ (or storage device of your choice). It walks through the array it is called on, passes each value to the function and then saves it to the floppy disk (Minions USB memory stick). The floppy disk doesn’t have to be a number, it can be an array etc. - just remember that it will stick to it’s type: if your floppy disk (64gb Sandisk micro SD card) is an array to begin with, the results of the function will be pushed to that array. If it is a number you can dictate what to do - add, subtract&nbsp;etc.

```
let jsReduce = nums.reduce((sum, num) => {
  if (moreThanFive(num)) {
    return sum + num;
  } else {
    return sum; // nums is unaffected still
  }
// The floppy disk here is the (number) 0 passed after the function:
}, 0);
// 30 (6 + 7 + 8 + 9)
```

This will go through our nums array, check if the value is moreThanFive. If it is, it will save it to the floppy disk (spiral bound, lined notebook).

You can think of it as a kind of map function, but all of the results are smooshed down into&nbsp;one.

![](https://cdn-images-1.medium.com/max/300/1*Xdsk3ImRVrfZ_KZB-qtAVA.jpeg)<figcaption>Reduced. Geddit?</figcaption>

This is probably the more complicated of the three. Take some time to make sure you get _what_ it has done, not necessarily _how_ it has done&nbsp;it.

So, let’s try writing our own reduce function:

```
const reduce = (floppyDisk, arr) => {
  for(let i = 0; i < arr.length; i++) {
    if (arr[i] > 5) {
      floppyDisk += arr[i];
    }
  };
  return floppyDisk; // nums is still not a mutant/zombie/whatever
}
```

This is a very simple version - it will only work with numbers, but you get the idea. The JS version is much more powerful - it can push to arrays&nbsp;etc.

BUT, you can see it is **still** just a forloop with an if check inside&nbsp;it.

I hope this has demistified these three higher-order functions. I think I was fairly confident in using them before now, but writing this has really cleared it up for&nbsp;me.

Give them a try, see how it works out for&nbsp;you.

If it helps, let me know - leave a comment, retweet or whatever.

If it’s wrong, let me&nbsp;know.

There may be a better way to do it than this, but I’ve tried to keep it clear and&nbsp;simple.

**REMEMBER KIDS: Reducing variables down to one letter REALLY doesn’t help anybody when they are trying to&nbsp;learn.**