Using loops instead of higher order functions
I came across a great article from Kirstian Poslek, titled
“One reduce() to rule them all”. It explains the reduce()
function quite
well.
I often feel though that using higher order functions are used in many cases where simple loops might be more legible.
The article ends with an example of a function that takes an array, and returns the maximum, minimum and average values. This is the sample from the article:
const data = [115, 26, 99];
const callbackFunction = function(
accumulator,
currentElement,
currentIndex,
array
) {
// Get the maximum by checking first if there is a maximum from the previous step
const maximum = accumulator.maximum
? // If there is, then check if the current element is higher than the previous maximum
accumulator.maximum < currentElement
? currentElement
: accumulator.maximum
: // If there isn't, use the current element right away
currentElement;
// Get the minimum by checking first if there is a minimum from the previous step
const minimum = accumulator.minimum
? // If there is, then check if the current element is lower than the previous maximum
accumulator.minimum > currentElement
? currentElement
: accumulator.minimum
: // If there isn't, use the current element right away
currentElement;
// Get the average by checking if we're at the last step (where it we can finally calculate the average)
const average =
currentIndex === array.length - 1
? (accumulator.average + currentElement) / array.length
: // If we're not at the last step, check if there even is a value from the previous step
accumulator.average
? accumulator.average + currentElement
: currentElement;
// Return the value for the next element
return {
maximum,
minimum,
average
};
};
const result = data.reduce(callbackFunction, {});
console.log(result); // Returns { maximum: 115, minimum: 26, average: 80 }
Curious if I could improve on that, I wrote my own version:
function getArrayStats(input) {
if (!input.length) return {};
let maximum = input[0];
let minimum = input[0];
let sum = 0;
for(const item of input) {
maximum = item > maximum ? item : maximum;
minimum = item < maximum ? item : minimum;
sum += item;
}
const average = sum / input.length;
return {
maximum
minimum,
average
};
}
I’ve had discussions like this with co-workers before, that would often swear that ‘functional’ versions of these types of operations are more legible to them.
I do use functions from the .map()
and .reduce()
family, but there’s a
threshold where I will often switch to classic loop if I worry it will be
hard for a future maintainer to understand what my code does. The above
example does pass that threshold for me.
But I recognize that this is pretty subjective. What do you think?