Skip to content
Advertisement

Splitting string that’s really an array?

I’m trying to split this string var raw = "GMYTEOR[RHE5DO,SG[A5D[CN[I,Q],EM[I,Q],M],E5D[C[NY,OA],O,Q],M5DC[MY,NA],U5DQ,Y5DCOA]]"

I manually split this out into the following patterns:

const valid_reults = [
    'GMYTEORRHE5DO',
    'GMYTEORSGA5DCNI',
    'GMYTEORSGA5DCNQ',
    'GMYTEORSGA5DEMI',
    'GMYTEORSGA5DEMQ',
    'GMYTEORSGA5DM',
    'GMYTEORSGE5DCNY',
    'GMYTEORSGE5DCOA',
    'GMYTEORSGE5DO',
    'GMYTEORSGE5DQ',
    'GMYTEORSGM5DCMY',
    'GMYTEORSGM5DCNA',
    'GMYTEORSGU5DQ',
    'GMYTEORSGY5DCOA',
]

I tried parsing it with JSON.parse but that didnt work for obvious reasons.

I also tried splitting the string by the brackets but that was a really bad idea and I couldn’t get it working after 20-30 mins of trying.

What’s the best way to convert that bizarre string format into a formatted array as shown in valid_results?

Advertisement

Answer

This should work:

function splitString(str) {
  // if there is no brackets a split will solve
  if (!str.includes('[')) {
    return str.split(',');
  }
  // finds first bracket
  const bracketsIdx = str.indexOf('[');
  // find the close bracket for it
  const closingBracketsIdx =
     findClosingBracketMatchIndex(str, bracketsIdx);
  if (closingBracketsIdx === -1) {
    // Invalid input, didn't find a close bracket
    throw Error()
  }
  // find all possibilities inside the bracket
  const expand = splitString(str.substring(
    bracketsIdx+1,
    closingBracketsIdx,
  ));
  return [
    // Remove duplicates
    ...new Set(expand.map(
      (expandedStr) => splitString(
        (
          // concatenate each possibility to what is
          // outside of the bracket
          str.substring(
            0,
          bracketsIdx,
          )
          + expandedStr
          + str.substring(
            closingBracketsIdx+1,
          )
        )
      )
    // since each call will return an array we flatten them
    ).flat())
  ];
}

function findClosingBracketMatchIndex(str, pos) {
  let openBracketCount = 1;
  for (let i = pos + 1; i < str.length; i++) {
    let char = str[i];
    if (char === '[') {
      openBracketCount++;
    } else if (char === ']') {
      openBracketCount--;
    }
    if (openBracketCount === 0){
      return i;
    }
  }
  return -1;
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement