Array.reduate mutating state outside not recommended?

Why are mutating variables outside the method .reduce()considered bad practice? In the example below, I mutate a variable declared externally from the reduction method. Why is this not recommended?

function balanceParens(string) {
    let max = 0;
    let res = string.split("").reduce((counter, char) => {
        // Handle if parens open and close out of order
        if (counter < 0) { 
          return counter;
        }
        // Add 1 for each open in order
        if (char === "(") {
          if(++counter > max) {
            max = counter;
          }
          return counter;
        }
        // subtract 1 for each close in order
        if (char === ")") {
          return --counter;
        }
        // handle use case if char is not a paren
        return counter;
    }, 0);
    console.log("Max depth was :", max);
    return !res;
}
console.log(balanceParens("((()(((())))))((((()))))"));
Run codeHide result
0
source share
2 answers

Why are mutating variables outside the method .reduce()considered bad practice?

Because you mix functionality with an imperative approach. Keep it in a single paradigm, not confuse everyone.

Would you go with

  • either reducewith a clean callback and no side effects

    function step({max: oldMax, counter: oldCounter}, char) {
      const counter = oldCounter + (char=="(") - (char==")");
      const max = counter > oldMax ? counter : oldMax;
      return {max, counter};
    }
    function maxParensLevel(string) {
      assert(hasBalancedParens(string));
      const {max, counter} = string.split("").reduce(step, {max:0, counter:0});
      return max;
    }
    
  • or a simple loop and two mutable variables

    function maxParensLevel(string) {
      assert(hasBalancedParens(string));
      let max = 0;
      let counter = 0;
      for (const char of string.split("")) {
        if (char == "(")
          counter++;
        else if (char == ")")
          counter--;
        if (counter > max)
          max = counter;
      }
      return max;
    }
    

but not both.

0
source

. @JordanRunning:

" , ? , forEach"

. :

function balanceParens(string) {
	let res = string.split("").reduce((state, char) => {
		// Handle if parens open and close out of order
		if (state.counter < 0) {
			return state;
		}
		// Add 1 for each open in order
		if (char === "(") {
			if (++state.counter > state.max) {
				state.max = state.counter;
			}
			return state;
		}
		// subtract 1 for each close in order
		if (char === ")") {
			state.counter = --state.counter;
			return state;
		}
		// handle use case if char is not a paren
		return state;
	}, {max: 0, counter: 0});
	console.log("Max depth was :", res.max);
	return !res.counter;
}

console.log(balanceParens("((()(((())))))((((()))))"));
Hide result
0

Source: https://habr.com/ru/post/1680907/


All Articles