This is the 6th article in my “examples series” for functional programming. Read about the series here, including links to previous and future examples.

This example is in TypeScript (like all the examples so far) and uses the underscore.js library.

In this example, I have a collection of “managed events.” In this system, a managed event is something like a blood drive, a walkathon or other non-trivial gathering taking place (often of a voluntary nature) on a certain date and time. It’s “managed” because someone is actively managing and coordinating the event. Over the course of year, several dozen (possibly several dozens) of these events will take place in different countries. Employees in Geneva are naturally more interested in events taking place in Geneva while folks in the U.S. are similarly focused on U.S. events.

I want to implement this method:

Get Me Some Countries

This method should return a string array with one entry for each unique country in the collection. E.g. [ “China”, “France”, “Germany”, “Japan”, “United States”].

A ManagedEvent’s data looks like this:

Manage Me, Baby

Getting back to _getSortedUniqueCountries — this method is going to be passed in an array of the managed events and needs to return back a sorted string array. Here are three different approaches that do the same thing and a bonus version that is just plain interesting:

Choices, choices

The first version gets the job done without using the underscore library. This is basically the same thing as what I wrote about here, so I won’t explain it again in this post.

Version two takes advantage of underscore’s uniq function. You pass in your object collection (ManagedEvents in this case) and a lambda function. The lambda function takes one ManagedEvent as an argument and returns back a value. In this case, it returns back the country of that managed event. Uniq keeps track of all the values it has already retrieved via that lambda function and once it finishes iterating, voila! You have a unique list of values. (Funnily enough, uniq itself isn’t really following FP principles; have a look here to see what I mean).

Version three accomplishes the same but takes a little shortcut by way of pluck. Instead of passing in a lambda function to do the work, you tell it which property from the object (ManagedEvent) to use while building up unique countries. This was the first time I “got” pluck and although it was satisfying to scratch that itch, it doesn’t look like a good long-term thing to do. I didn’t test it but I’m quite sure that this will cause an issue when you minimize the code. In version 2, it’s “plucking” a field called “Country” from the ManagedEvent object. However, when minimized, ManagedEvent’s Country property will be renamed to something like “A” and the pluck won’t find it.

Finally, the bonus version. This version doens’t return an array of string, but rather an array of ManagedEvent objects. It will return one ManagedEvent per each country. That’s not useful in this context since I really just need countries. However, it’s good to know that you *can* return complex objects this way and I’m sure there are other useful scenarios for it.

Note that the special value “ALL” (denoting “show me all events in all countries”) seeds the string array. The reduce/uniq logic then concatenates the unique list of countries to this seeded value. The concat function creates a new array by concatenating two arrays and is thus side-effect free. I could have used push instead, but that runs counter to functional programming and immutability in particular.

Lastly, note the use of the const keyword. In functional programming, we want stuff to be immutable and this tells the compiler (and other devs looking at it) that we at least intend immutability. There’s some important nuance with const, so look it up if you haven’t seen it before or if you think it means “constant” in the common sense meaning of the word. (See here, for instance). The previous posts in this series don’t use const but they probably should.

That’s it! As always, I hope this helps someone.

</end>