Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to early break reduce() method?

How can I break the iteration of reduce() method?

for:

for (var i = Things.length - 1; i >= 0; i--) {
  if(Things[i] <= 0){
    break;
  }
};

reduce()

Things.reduce(function(memo, current){
  if(current <= 0){
    //break ???
    //return; <-- this will return undefined to memo, which is not what I want
  }
}, 0)
like image 310
Julio Marins Avatar asked Sep 27 '22 09:09

Julio Marins


People also ask

How do you break a reduced function?

The answer is you cannot break early from reduce , you'll have to find another way with builtin functions that exit early or create your own helper, or use lodash or something.

What is the reduce () array method?

The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

Does reduce method work on strings?

We use reduce() when we need to analyze all of the elements in an array and return just a single value, it can transform the data from the array into a number, string, or an object.


2 Answers

UPDATE

Some of the commentators make a good point that the original array is being mutated in order to break early inside the .reduce() logic.

Therefore, I've modified the answer slightly by adding a .slice(0) before calling a follow-on .reduce() step, yielding a copy of the original array. NOTE: Similar ops that accomplish the same task are slice() (less explicit), and spread operator [...array] (slightly less performant). Bear in mind, all of these add an additional constant factor of linear time to the overall runtime + 1*(O(1)).

The copy, serves to preserve the original array from the eventual mutation that causes ejection from iteration.

const array = ['apple', '-pen', '-pineapple', '-pen'];
const x = array
    .slice(0)                         // create copy of "array" for iterating
    .reduce((acc, curr, i, arr) => {
       if (i === 2) arr.splice(1);    // eject early by mutating iterated copy
       return (acc += curr);
    }, '');

console.log("x: ", x, "\noriginal Arr: ", array);
// x:  apple-pen-pineapple
// original Arr:  ['apple', '-pen', '-pineapple', '-pen']

OLD

You CAN break on any iteration of a .reduce() invocation by mutating the 4th argument of the reduce function: "array". No need for a custom reduce function. See Docs for full list of .reduce() parameters.

Array.prototype.reduce((acc, curr, i, array))

The 4th argument is the array being iterated over.

const array = ['apple', '-pen', '-pineapple', '-pen'];
const x = array
.reduce((acc, curr, i, arr) => {
    if(i === 2) arr.splice(1);  // eject early
    return acc += curr;
  }, '');
console.log('x: ', x);  // x:  apple-pen-pineapple

WHY?:

The one and only reason I can think of to use this instead of the many other solutions presented is if you want to maintain a functional programming methodology to your algorithm, and you want the most declarative approach possible to accomplish that. If your entire goal is to literally REDUCE an array to an alternate non-falsey primitive (string, number, boolean, Symbol) then I would argue this IS in fact, the best approach.

WHY NOT?

There's a whole list of arguments to make for NOT mutating function parameters as it's a bad practice.

like image 144
Tobiah Rex Avatar answered Oct 25 '22 05:10

Tobiah Rex


Don't use reduce. Just iterate on the array with normal iterators (for, etc) and break out when your condition is met.

like image 36
Johann Avatar answered Oct 25 '22 06:10

Johann