Higher Order Arrow Functions Sometimes Inefficient?

Tell us what’s happening:

Though we use higher order arrow functions like in the code below, the solution for this is inefficient, isn’t it?
Reason: Filtering all the positive integers first and then squaring each of them later would double the time.

We could just do both functions’ activity in a single step by checking if it’s a positive integer and squaring it if the condition is true , right?

Your code so far


const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];
const squareList = (arr) => {

  const squaredIntegers = arr.filter((num) => Number.isInteger(num) && num >=0).map((num) => num*num);
  return squaredIntegers;
};
// test your code
const squaredIntegers = squareList(realNumberArray);
console.log(squaredIntegers);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/write-higher-order-arrow-functions

well, you could, but you need to do it with a different method

filter just removes items from the array, it doesn’t change those that stay. map change all items, can’t change the number of elements in an array

using reduce, if you learn how to do it, would let you using one single method and so iterating only once on the array

1 Like

Yes, but this is a good spot: every array method you use will go through a whole array, so:

// first run through array, filtering:
[4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2].filter(isPositiveIntegerFunction).map(squareFunction);
// second run through [filtered] array, mapping:
[4, 42, 6].map(squareFunction)
// end result:
[16, 1764, 36]

JavaScript is extremely quick, so this doesn’t tend to be a huge issue in practice. You can use reduce to do it in one step, but the code will be more difficult to read.

How do we do it using reduce() ? I’m just curious.

const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2]; 
const squareList = (arr) => {
  const squaredIntegers = arr.reduce((accumulator, num) => {
    if(num>0) accumulator.push(num*num);
    return accumulator
  }, []);
  return squaredIntegers; 
}; // test your code 
const squaredIntegers = squareList(realNumberArray); 
console.log(squaredIntegers);

basically, in the reduce, the accumulator starts as an empty array. For each number, we check if it’s positive and, if it is, we push it’s squared value onto that accumulator. One step, filter and map.

There is argument back and forth whether this is the better way. In theory, it’s a single pass through the array, so there’s that, but it is a little less readable than the filter/map version. It’s largely a matter of personal preference.

1 Like