I was working on the javascript code which required me to transform an algorithmic conditions into code. So first I have written the simple version as below.

The above code is hard to read because there are different tests in the form of if-else conditions, and also the nesting is 3 to 4 levels deep! One way to improve this code is to replace such conditions with Boolean functions, and then move all the magic numbers in variables.

But here, all the magic numbers are actually for the same purpose / value, we have to create a collection object – JSON as it is JavaScript. And if we see the conditions closely, it is checking the calculated value against a range and then setting the fixed value to the float. So, we cannot simply make variables for these numbers or replace the conditions with a straight forward Boolean methods.

What next?

To refactor this code, we have to first understand the whole logic and define a pseudo code. It looks something like following,

Now, from the above code it is clear that,

  1. There is a deep nesting, up to 3 levels. First we need to check over myDataVal, then inside that we need to check over amount and then inside that we need to check calculatedVal. So there is a relation between these data points, which we can define as a collection. In Javascript, we can create a JSON object holding all these data points and then write down a code to iterate over it and decide what to return.
  2. Each condition is basically checking that the given value falls in the range or not. So this is the second candidate for refactoring. We can have a function which gives us Boolean value confirming if range has the number or not.

So, let us do these two points first.

Ok, Now We have moved the data-points/configurable-numbers in the data object as shown, and converted the code to use that object. But this is still complex, I would say complex than the previous version of code! Also, if we want to add one more nested level, then this method would get complicated having 4th nested for loop inside!

Now What?

If we closely look at this version, we can see that the for loop is repeated thrice. It is doing the same thing again and again – validating the number with the array, looping over the internal JSON object and keep iterating until it reaches the level where it can access the JSON key ‘fixedVal‘.

So we can say still this code is not following DRY (Do not Repeat Yourself). To fix it, we need to remove the repetition. Let us recall the factorial problem, we can compare it with that. In most of the programming languages, iteration with repetition can be replaced with recursion! So lets see if we can refactor this again using recursive function. For that we need to consider the following,

  1. For loop can be replace with the recursive function such that same function calls itself until done.
  2. There are three diff. variables which are tested for inclusion in the range for each nested for loop – myDataValamount and calculatedVal as per this line ‘this._isDataRangeMatches(myDataVal,keyRange1)’.
    • So if we want to use recursion, we need to pass these variables in a way where the function can dynamically use them.
    • Can we pass them as Array or JSON? Array could be simpler, but array would need to be ordered accordingly. But then how we are going to know that value from which index needs to be read for current recursion call?
    • When we take a look at Array functions, there is one function called ‘.pop’ which gives the object last pushed and removes it from the array, exactly the stack behavior – LIFO. So that means, we can stack these three variables in the array in the order we want them to be popped, and call the recursive function!
  3. All other objects can be passed in as it is because we can always access the inner objects using JSON keys.

Now the code looks cleaner! We always need to be cautious about the simplicity of the code and use logical ideas to resolve complex problems!

At BoTree Technologies, we build web and mobile applications to add value to our client’s business. We align ourselves to ensure that our client benefits the most out of our engagement.

We work in Ruby on RailsPython, Java, React, Android, iOS and RPA as well.

Drop us a line to discuss how can we help take your business to the next level.