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; }