Anyone who has used list sorting of strings in LSL has probably realized that is sorts using an ascii sort. This can create an issue as ascii sorting is a bit different than the more 'human friendly' alpha sorting.
The attached jpg is an example of ascii sorting vs alpha sorting. I've also included a set of functions that I've used to accomplish this task. Currently, manual alphanumeric sorting is incredibly inefficient, it slow and requires far too much script memory. A function built in to LSL would be much more efficient.
Basically what I'm doing here:
1. Iterate through the unsorted list and cut the strings into chunks that seperate the letters /characters and numbers
2. Pad any numbers with zeros
3. Reassemble the string
4. Build a new list with the modified strings
5. Sort the new list
6. Iterate through the new sorted list and cut the strings into chunks that seperate the letters /characters and numbers
7. Remove the padding from any numbers
8. Reassemble the strings
9. Build an output list in the same order as the sorted list, minus the padding on the numbers.
This is very limited and uses a ton of memory to process any large lists. I hit pretty close to the memory limit sorting a list of 128 strings(approximately 7 characters in length each) and the sort took 76 seconds to complete...
To use the function:
list sortedlist = alphaSort(list unsortedlist);
LSL:
list numbers = ["0","1","2","3","4","5","6","7","8","9"];
integer padding = 16;
string zeros = "000000000000000";
integer isNumber(string str)
{
integer len = llStringLength(str) - 1;
integer x;
for(x=0;x<=len;x++)
{
string chkStr = llGetSubString(str,x,x);
if(llListFindList(numbers, (list)chkStr) == -1)
{
return FALSE;
}
}
return TRUE;
}
string addPad(string num)
{
integer padCnt = (padding - llStringLength(num)) - 1;
return llGetSubString(zeros, 0, padCnt) + num;
}
string dePad(string num)
{
integer tmpInt = (integer)num;
num = (string)tmpInt;
return num;
}
string chunk(string data)
{
string output;
integer numChunk;
integer len = llStringLength(data) -1;
integer x;
for(x=0;x <= len; x++)
{
string tmpChar = llGetSubString(data, x, x);
if(isNumber(tmpChar))
{
if(numChunk == FALSE)
{
numChunk = TRUE;
output = output + "|" + tmpChar;
}
else
{
output = output + tmpChar;
}
}
else
{
if(numChunk == TRUE)
{
numChunk = FALSE;
output = output + "|" + tmpChar;
}
else
{ output = output + tmpChar; } }
}
}
return output;
}
string chunkPad(string data)
{
string output;
list tmpList = llParseString2List(data, ["|"], [""]);
integer len = llGetListLength(tmpList) -1;
integer x;
for(x=0; x<=len; x++)
{
string tmpStr = llList2String(tmpList, x);
if(isNumber(tmpStr))
{
output = output + addPad(tmpStr);
}
else
{
output = output + tmpStr;
}
}
return output;
}
string chunkDePad(string data)
{
string output;
list tmpList = llParseString2List(data, ["|"], [""]);
integer len = llGetListLength(tmpList) -1;
integer x;
for(x=0; x<=len; x++)
{
string tmpStr = llList2String(tmpList, x);
if(isNumber(tmpStr))
{
output = output + dePad(tmpStr);
}
else
{ output = output + tmpStr; } }
}
return output;
}
//This is the main function to call....
list alphaSort(list data)
{
list tmpList = [];
list output= [];
integer len = llGetListLength(data) -1;
integer x;
for(x=0;x<=len;x++)
{
string inpStr = llList2String(data, x);
string outChunk = chunk(inpStr);
string outPad = chunkPad(outChunk);
tmpList = tmpList + (list)outPad;
}
tmpList = llListSort(tmpList, 1, TRUE);
for(x=0;x<=len;x++)
{
string inpStr = llList2String(tmpList, x);
string outChunk = chunk(inpStr);
string outDePad = chunkDePad(outChunk);
output = output + (list)outDePad;
}
return output;
}