How do I split an string of alphabets and numbers into arrays and sort them respectively in javascript

Viewed 54

if I have a string AYUKB17053UI903TBC. I want a function to return ABKUY01357IU039BCT. So every alphabetical part of the string is sorted, as well as the numerical part. But they retain their original orders in the string...

We can assume that the input only contains number and English letters

I came up with a solution but I don't think it is elegant.

const string1 = 'AYUKB17053UI903TBC'
const string2  = `ABKUY01357IU039BCT`


function fn1(string1) {
  let tempArray = [[]]
  for (const char of string1) {
    let lastCharIsNumber
    let currentCharIsNumber
    const lastArray = tempArray[tempArray.length - 1]
    if(!lastArray.length){
      lastArray.push(char)
      continue
    }
    currentCharIsNumber = !Number.isNaN(Number(char))
    lastCharIsNumber = !Number.isNaN(Number(lastArray[lastArray.length - 1]))
    if (currentCharIsNumber && lastCharIsNumber)  lastArray.push(char)
    else if (!currentCharIsNumber && !lastCharIsNumber) lastArray.push(char)
    else tempArray.push([char])
  }

  tempArray.forEach(item => item.sort())

  return tempArray.map(array => array.join('')).join('')
}

console.log(fn1(string1) === string2); // true

Can anyone help to improve my solution?

1 Answers

Got a much shorter solution for you:

let str = 'AYUKB17053UI903TBC';
let res = str.match(/[a-zA-Z]+|\d+/gi).map((substr) => {
  return substr.split('').sort().join('');
}).join('');

Explanation:

  1. Building the regex:

    1.1. We match numbers with either [0-9] or \d notation.

    1.2. We match letters with [a-zA-Z].

    1.3. We need to match at least one number in each occurrence or at least one letter in each occurrence. Therefore we use the plus sign + to indicate that we want one or more of each in each match.

    1.4. The match function will return an array with all occurrences that our regex match in given string.

    1.5. We use a flag after the last slash to indicate that we do not care about case-sensitivity, in this case the letter i after / in the regex declaration.

    1.6. We also use the flag g to avoid stopping the matches after the first match.

  2. Using the regex with the function match we separate the string into multiple groups that have only numbers or letters. That is, the regex will return an array of strings.

  3. For each group we use the sort function to put them in order, if you have case-sensitive strings you may need to provide another sort method.
  4. We finally join everything back to get them in order.
Related