JavaScript split by space ignoring parentheses

We can balance the string out by adding the missing parentheses at the end.

Note that a situation like

"attribute1 in (a, b, c attribute2 in (d, e"

would result in

[ 'attribute1', 'in', '(a,', 'b,', 'c', 'attribute2', 'in', '(d, e' ]

and the solution assumes this is the expected outcome.

If yes – here’s the solution:

/**
 * @param {string} s
 * @returns {string[]}
 */
function split(s) {
  let unclosed_count = 0;

  // count unclosed parentheses
  for (let i = 0; i < string.length; i++) {
    if (s[i] == '(') {
      unclosed_count++;
    } else if (s[i] == ')') {
      unclosed_count--;
    }
  }

  // close off the parentheses
  for (let i = 0; i < unclosed_count; i++) {
    s += ')';
  }

  // split
  let words = s.split(/(?!\(.*)\s(?![^(]*?\))/g);

  // remove the added parentheses from the last item
  let li = words.length - 1;
  words[li] = words[li].slice(0, -unclosed_count);

  return words;
}

let string = 'attribute1 in (a, b, c) attribute2 in (d, e';
let words = split(string);

console.log(words);
// => [ 'attribute1', 'in', '(a, b, c)', 'attribute2', 'in', '(d, e' ]

cheers!


also worth considering a case where instead of the opening brackets ( being unmatched, there would exist some closing brackets ) that are unmatched aswell.

i.e. "attribute1 in a, b, c) attribute2 in d, e)"

this was not mentioned in the problem so it’s not inside the solution either, but in case this matters, you’d want to do the same thing we did with unclosed_count, but reverse, with i.e. unopened_count.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top