Check whether string of braces, brackets, and parentheses is balanced The Task

is taken from codewars:


  Write a function that takes a string of braces, and determines if the
  order of the braces is valid. It should return true if the string is
  valid, and false if it's invalid.
  
  All input strings will be nonempty, and will only consist of
  parentheses, brackets and curly braces: ()[]{}.
  
  What is considered Valid? A string of braces is considered valid if
  all braces are matched with the correct brace.
  
  Examples
  
  
  (){}[]   =>  True
  ([{}])   =>  True
  (}       =>  False
  [(])     =>  False
  [({})](] =>  False
  


My solution

const areBracesBalanced = brc =&gt; {
  const brace = Object.freeze({
    "(": [],
    "[": [],
    "{": [],
  });

  const removeBrace = b =&gt; brace[b].splice(-1, 1);
  const getLastBraceIndex = b =&gt; brace[b][brace[b].length - 1]
  const braceExists = b =&gt; !brace[b].length;
  const isBraceBeforeClosed = (before, current) =&gt; braceExists(before) || getLastBraceIndex(before) &lt; getLastBraceIndex(current);

  const braceIsBalanced = (b, i) =&gt; {
    switch (b) {
      case "(":
      case "[":
      case "{":
        return brace[b].push(i);
      case ")":
        return isBraceBeforeClosed("[", "(") &amp;&amp;
               isBraceBeforeClosed("{", "(") &amp;&amp;
               removeBrace("(");
      case "]":
        return isBraceBeforeClosed("(", "[") &amp;&amp;
               isBraceBeforeClosed("{", "[") &amp;&amp;
               removeBrace("[");
      case "}":
        return isBraceBeforeClosed("(", "{") &amp;&amp;
               isBraceBeforeClosed("[", "{") &amp;&amp;
               removeBrace("{");
      default:
        // be a good code...
    }
  };

  return[...brc]
    .every(braceIsBalanced) &amp;&amp; !Object.values(brace).flat().length;
}
Your solution is complicated due to the use of three separate stacks:


For each closing character, you have to cross-validate the two other types of delimiters.  (If you had to handle a fourth type of matching characters, such as &lt; and &gt;, it would be even messier.)
At the end, you need to write !Object.values(brace).flat().length to verify that all of the stacks have been cleared.


I also think that the use of Object.freeze() is overkill.

Your removeBrace() helper can use Array.prototype.pop() instead.

Suggested solution

Keep all of the state in one combined stack.



const areBracesBalanced = brs =&gt; {
  let expectCloseStack = [];
  return [...brs].every(b =&gt; {
    switch (b) {
      case "(": return expectCloseStack.push(")");
      case "[": return expectCloseStack.push("]");
      case "{": return expectCloseStack.push("}");

      case ")":
      case "]":
      case "}":
        return expectCloseStack.pop() === b;
    }
  }) &amp;&amp; !expectCloseStack.length;
};

console.log(areBracesBalanced("[({})](]"));