subscribe

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?

Web mentions