I'm not sure exactly what your metric is for being "elegant", but here's a bit of a different approach that I think is fairly "clean" and "simple" to follow: <!-- begin snippet: js hide: false console: true babel: false --> <!-- language: lang-js --> const string1 = 'AYUKB17053UI903TBC'; const string2 = 'ABKUY01357IU039BCT'; function sortPieces(str) { const piecesArray = []; let lastPiece = []; let lastType; for (const char of str) { const nextType = (char >= "0" && char <= "9") ? "number" : "letter"; if (nextType === lastType || !lastType) { // either same type as previous char or first char in string lastPiece.push(char); } else { // different type of char than previous char, start a new piece piecesArray.push(lastPiece.sort()); lastPiece = [char]; } lastType = nextType; } piecesArray.push(lastPiece.sort()); return piecesArray.flat().join(""); } let result = sortPieces(string1) console.log(result === string2, result); <!-- end snippet -->