Talking from my empirical point of view, the functional way in JavaScript is not like barking up the wrong tree, many common use cases are not rocket science.
As others, I make use of the imperative paradigm with ordinary coding blocks like the conditional and iteratives ones, but here the language gives us the tools for solving things the easier and the faster way. But before taking action, it’s always better if you know your stuff.
Let’s suppose that a given use case comes up with a large array of some kind of complex object, like an ecommerce order with some several properties.
The data we are going to work with, follows the structure shown by the figure below.
For those who feel more comfortable with a class diagram than with a plain object structure, we can model it as its follows.
As always, requirements came up with a typical listing of functionalities like:
- retrieving which products are in stock and which aren’t by labeling available ones as available and the others as out of stock.
- there couldn’t be any line item for unstocked products. So, at the time of picking the saleable items from the list, those which are not available must be disabled.
- retrieving the total of the order.
And some business requirements may apply at some specific situations:
- no item line should exceed the maximum of 10 units.
- if an item line reaches the maximum quantity, the last item is free.
- for the order whose total value exceeds $5500.00 apply the 5% discount over the entire buy.
Taking place on the problem, we can suppose that the current dataset has been given. Then we can solve each requirement as follows:
Retrieve which products are in stock and which are not by labeling them as available and out of stock respectively
As we already know, our datasource is an array of orders and each one has an inner array of line items which describes the amount of a certain product offered by the ecommerce shop. The goal is to reach the stock property on the product to do the corresponding labeling.
Taking in mind the requirement does not specify the structure of the result, we can return an array of objects describing the product we have just processed and its corresponding label.
Reduction
The reduction is the process of converting an expression to a simpler form. So having an expression, the reduction process will produce the only possible answer.
(5 + (2 + 10)) —> (5 + 12) —> 17
The same occurs with JavaScript, a reducer function is required when calling to reduce to produce the reduction result. Taking the same example as above:
[5, 2, 10].reduce((total, current) => total + current, 0); // 17
The reducer function provided (better known on this context as callback) takes four arguments:
reduce(callback(accumulator, current [, index]){}[,initialValue]);
- the accumulator, where the last reduced result is stored
- the current value, which is the next value to be processed
- the index of the current value
- the initial value
Mapping
The mapping process does the projection from the current domain to a different one. The thing is, to map is doing the switching between domains applying a transformation function which takes an element from the first context and returns a new element corresponding to the second context.
Let's say we need to capitalize a list of names
[“joe”, “bob”, “rose”].map((name) => some_utility.capitalize(name));
//[“Joe”, “Bob”, “Rose”]
Calling the map function requires a callback which takes two arguments:
map(callback(current [, index]){});
- the current value to be transformed;
- the index of the current value.
Suppose the requirement we have just resolved accomplished the specified by the business, but suddenly an order appears without line items or some line item shows some quantity and none product is related. Will the code survive to this unexpected situation?
The concept of preventive programming is not commonly known but its usage does, furthermore the idea of preventing a future disaster comes to our minds forcing us to write some extra code. In this case, we forgot to consider the worst scenario and now we have to fix it.
As we know the causes of the problems, the solution is simple. First, we need to take out the orders with no line items. After that, remove the line items who have no product related.
To do this, make use of the filter function which takes a filtering expression that must return a boolean on each evaluation. The required callback takes two arguments:
filter(callback(current [, index]){});
- the current value to be evaluated
- the index of the current value
And with this fix, no order should appear without line items and no line item should be processed if it has not a related product.
Hey, thanks for reading! This is the first article from a series where I am going to resolve the requirements listed before, using a similar approach and improving the examples with more accurate solutions. Just saying, the code here can be improved (even with other JavaScript functions), the goal is to show the usage of reduce, map and filter.
Please, let me know if you like the article by leaving a comment or clicking on the ❤ button.
Top comments (0)