June 25, 2012

Sorting a String

Filed under: Scripting — Marcus Tettmar @ 1:22 pm

In the forums this morning PepsiHog asked for some code to sort a string of numbers.

We have a built-in method for sorting arrays. But here we want to sort a string of characters. E.g. we want the string “4731” to end up as “1347”.

I ended up writing a reusable subroutine which will sort any length string alphanumerically. I thought I’d post it here as it demonstrates a few useful ideas:

//CharSort, parm1: the string to sort, parm2: name of variable to return
SRT>CharSort
  Let>LOCALVARS=1
  Let>tmp=
  RegEx>.,CharSort_Var_1,0,matches,nm,0
  ArraySort>matches
  Let>x=0
  Repeat>x
    Let>x=x+1
    Let>this_char=matches_%x%
    Let>tmp=%tmp%%this_char%
  Until>x=nm
  Let>LOCALVARS=0
  Let>%CharSort_Var_2%=tmp
END>CharSort

To use the subroutine do something like:

Let>MyString=317536492750930
GoSub>CharSort,MyString,{"MyString"}
MessageModal>MyString

This demonstrates a number of things:

– How we can call a subroutine with parameters, and how we can use one of those parameters to set a “result” variable (note the second parameter is set to a string value, and the subroutine sets a variable with this name to the result).

– How we use LOCALVARS to ensure the subroutine has local scope (except when we need to set the return variable). This is important for functions we might re-use elsewhere and drop into other scripts, as we would want to avoid the subroutine modifying any existing script variables. By using local scope we make sure the variables used in the subroutine are local only to that subroutine.

The subroutine works first by splitting the string into an array of characters. It does this by using a Regular Expression which identifies all characters (“.”). RegEx returns an array of matches, which will therefore be all the characters in the string (because “.” means match any character). We can then sort this array using ArraySort and then finally loop through the array and concatenate each item back into a string.