;==========================================================================================================================================; Worth to know for sorting in WinBatch.;; This is an attempt to understand what is going on with the data; while using WinBatch native sorting functions (ItemSort, BinarySort); in comparison to user coded sorting algorithms working with WinBatch arrays.;; Detlev Dalitz.20090519.;==========================================================================================================================================GoSubDEFINE_FUNCTIONS;--------------------------------------------------------------------------------------------------; Define a string list with alpha, numerical and special characters.strDelimiter=","strItemList="A,B,C,c,\z,6.67E-11,-196,0,0.07,+0.07,1,+,-,"; 14 items.intElements=ItemCount(strItemList,strDelimiter);--------------------------------------------------------------------------------------------------; Define three arrays.arrA=Arrayize(strItemList,strDelimiter); 'Automatic' array set from stringlist.arrB=ArrDimension(intElements); Each element set manually.arrB[0]="A"; 2 = VT_STRINGarrB[1]="B"; 2 = VT_STRINGarrB[2]="C"; 2 = VT_STRINGarrB[3]="c"; 2 = VT_STRINGarrB[4]="\z"; 2 = VT_STRINGarrB[5]="6.67E-11"; 2 = VT_STRINGarrB[6]="-196"; 2 = VT_STRINGarrB[7]="0"; 2 = VT_STRINGarrB[8]="0.07"; 2 = VT_STRINGarrB[9]="+0.07"; 2 = VT_STRINGarrB[10]="1"; 2 = VT_STRINGarrB[11]="+"; 2 = VT_STRINGarrB[12]="-"; 2 = VT_STRINGarrB[13]=""; 2 = VT_STRINGarrC=ArrDimension(intElements); Each element set manually.arrC[0]="A"; 2 = VT_STRINGarrC[1]="B"; 2 = VT_STRINGarrC[2]="C"; 2 = VT_STRINGarrC[3]="c"; 2 = VT_STRINGarrC[4]="\z"; 2 = VT_STRINGarrC[5]=6.67E-11;32 = VT_FLOATNUMarrC[6]=-196; 1 = VT_INTEGERarrC[7]=0; 1 = VT_INTEGERarrC[8]=0.07;32 = VT_FLOATNUMarrC[9]="+0.07"; 2 = VT_STRINGarrC[10]=1; 1 = VT_INTEGERarrC[11]="+"; 2 = VT_STRINGarrC[12]="-"; 2 = VT_STRINGarrC[13]=""; 2 = VT_STRING;--------------------------------------------------------------------------------------------------; Note: The GnomeSort sorting algorithm is slow and only used here to keep the example simple.;--------------------------------------------------------------------------------------------------; Array sorting with 'ordinal' comparer function 'ChrStringToHex'.intSortMode=0; Sorting uses 'ordinal' comparer.arrA=udfArrayGnomeSort(arrA,intSortMode)strList0A=udfArrayItemize(arrA,strDelimiter); ",+,+0.07,-,-196,0,0.07,1,6.67E-11,A,B,C,\z,c"strList0AVT=udfArrayGetListVT(arrA,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrB=udfArrayGnomeSort(arrB,intSortMode)strList0B=udfArrayItemize(arrB,strDelimiter); ",+,+0.07,-,-196,0,0.07,1,6.67E-11,A,B,C,\z,c"strList0BVT=udfArrayGetListVT(arrB,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrC=udfArrayGnomeSort(arrC,intSortMode)strList0C=udfArrayItemize(arrC,strDelimiter); ",+,+0.07,-,-196,0,0.07,1,6.67000000e-011,A,B,C,\z,c"strList0CVT=udfArrayGetListVT(arrC,strDelimiter); "2,2,2,2,1,1,32,1,32,2,2,2,2,2";--------------------------------------------------------------------------------------------------; Array sorting with 'math symbol' comparer.intSortMode=1; Sorting uses 'math' comparer.arrA=udfArrayGnomeSort(arrA,intSortMode)strList1A=udfArrayItemize(arrA,strDelimiter); ",-,\z,+,-196,0,6.67E-11,+0.07,0.07,1,A,B,c,C"strList1AVT=udfArrayGetListVT(arrA,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrB=udfArrayGnomeSort(arrB,intSortMode)strList1B=udfArrayItemize(arrB,strDelimiter); ",-,\z,+,-196,0,6.67E-11,+0.07,0.07,1,A,B,c,C"strList1BVT=udfArrayGetListVT(arrB,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrC=udfArrayGnomeSort(arrC,intSortMode)strList1C=udfArrayItemize(arrC,strDelimiter); ",-,\z,+,-196,0,6.67000000e-011,+0.07,0.07,1,A,B,c,C"strList1CVT=udfArrayGetListVT(arrC,strDelimiter); "2,2,2,2,1,1,32,2,32,1,2,2,2,2";--------------------------------------------------------------------------------------------------; Array sorting with 'word' comparer function 'StrCmp'.intSortMode=2; Sorting uses 'word' comparer.arrA=udfArrayGnomeSort(arrA,intSortMode)strList2A=udfArrayItemize(arrA,strDelimiter); ",-,\z,+,+0.07,0,0.07,1,-196,6.67E-11,A,B,c,C"strList2AVT=udfArrayGetListVT(arrA,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrB=udfArrayGnomeSort(arrB,intSortMode)strList2B=udfArrayItemize(arrB,strDelimiter); ",-,\z,+,+0.07,0,0.07,1,-196,6.67E-11,A,B,c,C"strList2BVT=udfArrayGetListVT(arrB,strDelimiter); "2,2,2,2,2,2,2,2,2,2,2,2,2,2"arrC=udfArrayGnomeSort(arrC,intSortMode)strList2C=udfArrayItemize(arrC,strDelimiter); ",-,\z,+,+0.07,0,0.07,1,-196,6.67000000e-011,A,B,c,C"strList2CVT=udfArrayGetListVT(arrC,strDelimiter); "2,2,2,2,2,1,32,1,1,32,2,2,2,2";--------------------------------------------------------------------------------------------------; Stringlist sorting.strListD=ItemSort(strItemList,strDelimiter); ",-,\z,+,+0.07,0,0.07,1,-196,6.67E-11,A,B,c,C"; Note: WinBatch function BinarySort with default sort key @STRING works alike.;--------------------------------------------------------------------------------------------------; Summary;; 1.; WinBatch native functions 'ItemSort' and 'BinarySort' internally use a 'word' sort algorithm; (see example output: strListD).;; 2.; If someone wants sorting an array and needs compatible result to 'ItemSort' and 'BinarySort',; then the sorting comparer must be a 'word sort' compatible function; like the WB native function 'StrCmp' does support.;; 3.; 'Math sorting' (<,<=,==,>=,>) gives other result than using 'word sorting' (StrCmp).; 'Word sorting' (StrCmp) gives other result than using 'Ordinal sorting' (ChrStringToHex).; 'Ordinal sorting' (ChrStringToHex) gives other result than using 'Math sorting' .;; 4.; Each sorting comparer mode has its own behaviour when sorting various datatypes at once.;; 5.; On 'word sorting' a group of numerical chars with leading minus symbol '-'; (a negative numberstring resp. a negative integer) is treated as a string with leading hyphen.;; 6.; On 'math sorting' an array element with VarType VT_STRING which contains a string that can be; evaluated to a number (integer, floatnum) is treated during the comparison as having a; numerical datatype VT_INTEGER resp. VT_FLOATNUM.;--------------------------------------------------------------------------------------------------Exit;==========================================================================================================================================;==========================================================================================================================================:DEFINE_FUNCTIONS;==========================================================================================================================================;------------------------------------------------------------------------------------------------------------------------------------------#DefineFunctionudfArrayGnomeSort(arrArray,intSortMode)If!ArrInfo(arrArray,-1)ThenReturnArrDimension(0); Invalid input array, return empty valid dim-0 array.IfArrInfo(arrArray,0)!=1ThenReturnArrDimension(0); Only dim-1 array allowed, return empty valid dim-0 array.intElements=ArrInfo(arrArray,1)IfintElements==0ThenReturnArrDimension(0); Input array has no elements, return empty valid dim-0 array.IfintElements==1ThenReturnarrArray; Input array has only one element, return the input array.SwitchintSortModeCase0intI=1WhileintI<intElementsIfChrStringToHex(arrArray[intI-1])<=ChrStringToHex(arrArray[intI])intI=intI+1ElseArraySwapElements(arrArray,intI-1,0,0,0,0,intI,0,0,0,0)intI=Max(1,intI-1)EndIfEndWhileBreakCase1intI=1WhileintI<intElementsIfarrArray[intI-1]<=arrArray[intI]intI=intI+1ElseArraySwapElements(arrArray,intI-1,0,0,0,0,intI,0,0,0,0)intI=Max(1,intI-1)EndIfEndWhileBreakCase2intI=1WhileintI<intElementsIfStrCmp(arrArray[intI-1],arrArray[intI])<1intI=intI+1ElseArraySwapElements(arrArray,intI-1,0,0,0,0,intI,0,0,0,0)intI=Max(1,intI-1)EndIfEndWhileBreakEndSwitchReturnarrArray;..........................................................................................................................................; Gnome Sort - The Simplest Sort Algorithm; The simplest sort algorithm is not Bubble Sort..., it is not Insertion Sort..., it's Gnome Sort!; Gnome Sort is based on the technique used by the standard Dutch Garden Gnome (Du.: tuinkabouter).; Here is how a garden gnome sorts a line of flower pots.; Basically, he looks at the flower pot next to him and the previous one;; if they are in the right order he steps one pot forward, otherwise he swaps them and steps one pot backwards.; Boundary conditions: if there is no previous pot, he steps forwards; if there is no pot next to him, he is done.; Dick Grune / dick@cs.vu.nl / http://www.cs.vu.nl/~dick/gnomesort.html;; IntSortMode = 0 ... 'Ordinal' sort using 'ChrStringToHex'.; IntSortMode = 1 ... 'Math' sort using '<='.; IntSortMode = 2 ... 'Word' sort using 'StrCmp'.;; Ported and tuned to WinBatch by Detlev Dalitz.20090518.;..........................................................................................................................................#EndFunction;------------------------------------------------------------------------------------------------------------------------------------------;----------------------------------------------------------------------------------------------------------------------#DefineFunctionudfArrayItemize(arrArray,strDelimiter)If!ArrInfo(arrArray,-1)ThenReturn""; No array.If!ArrInfo(arrArray,6)ThenReturn""; No elements.IfArrInfo(arrArray,0)>1ThenReturn""; Too much dimensions.strItemList=""intHigh=Max(ArrInfo(arrArray,1)-1,0)intLow=0ForintElem=intLowTointHighIf!!VarType(arrArray[intElem])strItemList=strItemList:strDelimiter:arrArray[intElem]ElsestrItemList=strItemList:strDelimiterEndIfNextReturnStrSub(strItemList,2,-1);----------------------------------------------------------------------------------------------------------------------; This UDF "udfArrayItemize" converts a given dim-1 array into an itemlist; with each item separated by delimiter character.;; Example: strMyItemList = udfArrayItemize (arrMyArray, @TAB); Creates an itemList from array.;; Note:; This UDF supports only dim-1 array.; An array element which is not initialized has a Vartype=0 (undefined).; Therefore an empty item will be appended to target itemlist.;; Detlev Dalitz.20020718.20090508.20090516.;----------------------------------------------------------------------------------------------------------------------#EndFunction;----------------------------------------------------------------------------------------------------------------------;------------------------------------------------------------------------------------------------------------------------------------------#DefineFunctionudfArrayGetListVT(arrArray,strDelimiter)If!ArrInfo(arrArray,-1)ThenReturn""; Invalid input array, return empty string.IfArrInfo(arrArray,0)!=1ThenReturn""; Only dim-1 array allowed, return empty string.intElements=ArrInfo(arrArray,1)IfintElements==0ThenReturn""; Input array has no elements, return empty string.intHigh=intElements-1intLow=0strListVT=""ForintI=intLowTointHighstrListVT=ItemInsert(VarType(arrArray[intI]),-1,strListVT,strDelimiter)NextReturnstrListVT;..........................................................................................................................................; Detlev Dalitz.20090516.;..........................................................................................................................................#EndFunction;----------------------------------------------------------------------------------------------------------------------;==========================================================================================================================================Return; from DEFINE_FUNCTIONS;==========================================================================================================================================