Bro, do you even map ? — MapReduce demystified

Written by aherve | Published 2016/12/01
Tech Story Tags: javascript | functional-programming | mapreduce

TLDRvia the TL;DR App

I’ve seen a lot of people struggling to understand map/reduce functions. They either think it’s too complicated to understand, or they think it’s a “big data thing” they won’t need.

Well guess what, I strongly disagree.

You can read this if you are wondering what a map/reduce is, or perhaps to convince your boss that using map/reduce in real-life apps is an awesome style-guide tip \o/

Or perhaps just for fun. Because programming is fun. We all know that.

Let’s play a game of “what does this code do?”

To play this awesome game, let’s pretend you are new to programming. You don’t have 10 years of experience at reading weird, imperative code. You are asked to read a piece of code in order to understand what it does.

  • Imperative style (difficulty: harder than it should be):

Soluce: Perhaps you didn’t even realized it, but you had to actually imagine you’re the computer, and follow the lines until you compute in your head the kind of result you would expect from this. If you’re even better, you probably figured out that this code was intended to sum the square numbers of the odd numbers of our input array.

Was that really simple ?

  • Functional style (difficulty: easy. Unless you’re too much used to imperative style. And you should change that. Seriously.):

This code does the same thing. But instead of reading how to get the result, this emphasis what the result should be. It is actually almost literally saying:

  • start with our numbers input
  • select odd numbers
  • compute all their squares
  • sum the result

Which is about exactly how you would describe this algorithm if you were asked to. Details of what an odd number is, what a square is are also available, but you don’t have to read it thoroughly to get the big picture.

Want another example ? How about a recommendation algorithm. This is complicated stuff. Not a simple numbers sum.We will use typescript for even more readability:

I personally think this is some quite readable code. The 6 first lines should be enough so that you get what’s going on here.

If you’re not convinced enough, try to imagine doing the same with forEach loops.

2. What kind of magic is this ?

If you’re totally new to map/reduce/filter operators, here’s a very simple description of what they are intended to do:

  • map will simply apply a function to all the elements of an array. So basically, [x, y, z].map(f) will return a new array that contains[f(x), f(y), f(z)]. Note that both you and the compiler know that the output will have same size as the input. Also, if f returns a number, then you’re guaranteed to obtain an array of numbers. Smart languages like typescript can take advantage of this, and so does anyone who read your code
  • filter will simply select some elements in your array, by testing them against the provided function. An array of numbers will still return an array of numbers, but its size will probably have changed. Note that your original array is remained unchanged through the process.
  • reduce will “crush” an array to return some value. Unlike map, the reduce function will take the array as a whole, and compute something on it. In our scenario, we added every value until we get the sum of the array of the elements. Typical examples are computation of sums, averages, or object constructions. for example:

Soo… no more _forEach_ ?

Well, I think forEach is ok if you want to iterate over objects, while returning nothing each time you do so.

myArray.forEach(console.log) looks ok to me. using a map would only return an array of nothing. We obviously ignore the result here so it’s ok.

However, myArray.forEach(someFunctionThatReturnsSomething) is probably wrong. Most of the time you want to do something with the result.

Conclusion

Congrats, map/reduce is no longer such a mystery for you.

Or perhaps it is ? Freel free to ask or drop some comments !


Published by HackerNoon on 2016/12/01