udfArrDistributionSort
arr udfArrDistributionSort (arr, int)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayDistributionSort (arrArray, intKeyCount)
If !ArrInfo (arrArray, -1) Then Return ArrDimension (1) ; Invalid input array, return empty valid dim-1 array.
If ArrInfo (arrArray, 0) != 1 Then Return ArrDimension (1) ; Only dim-1 array allowed, return empty valid dim-1 array.
intElements = ArrInfo (arrArray, 1)
If intElements == 0 Then Return ArrDimension (1) ; Input array has no elements, return empty valid dim-1 array.
If intElements == 1 Then Return arrArray ; Input array has only one element, return the input array.
intHigh = intElements - 1
intLow = 0

; How many different keys exist?
; If the number is known and given by parameter, then following computing is not necessary.
If !intKeyCount
   strItemList = ""
   For intI = intLow To intHigh
      If !ItemLocate (arrArray [intI], strItemList, @TAB) Then strItemList = ItemInsert (arrArray [intI], -1, strItemList, @TAB)
   Next
   intKeyCount = ItemCount (strItemList, @TAB)
EndIf

arrBins = ArrDimension (intKeyCount)
arrArrayStart = ArrDimension (intKeyCount)
arrArraySave = ArrDimension (intElements)

ArrInitialize (arrBins, 0)
ArrInitialize (arrArrayStart, 0)

For intI = intLow To intHigh
   arrArraySave [intI] = arrArray [intI]                        ; Copy Array to ArraySave.
   intIndexBins = Max (0, Char2Num (arrArray [intI]) - 65)      ; Hier die entsprechende Abbildungsfunktion anwenden.
   arrBins [intIndexBins] = 1 + arrBins [intIndexBins]          ; Count occurrences of each key value.
Next

; Compute the start position of each bin.
intPos = 0
intKeyHigh = intKeyCount - 1
For intI = 1 To intKeyHigh
   intPos = intPos + arrBins [intI - 1]
   arrArrayStart [intI] = intPos
Next

; Deal the saved array back to the original.
For intI = intLow To intHigh
   intIndexSave = Max (0, Char2Num (arrArraySave [intI]) - 65)  ; Hier die entsprechende Abbildungsfunktion anwenden.
   intStartIndex = arrArrayStart [intIndexSave]
   arrArray [intStartIndex] = Num2Char (intIndexSave + 65)      ; Hier die entsprechende _inverse_ Abbildungsfunktion anwenden.
   arrArrayStart [intIndexSave] = 1 + arrArrayStart [intIndexSave]
Next

Drop (arrBins, arrArraySave, arrArrayStart)
Return arrArray
;..........................................................................................................................................
; Is this an example for ideal hashing?
;
; Adopted from Pascal source published by
; James L. Allison, 1703 Neptune Lane, Houston, Texas  77062, Dec 22, 1988.
; "This is a real screamer, but it takes a lot of space,
; and is hard to package for inclusion in a library.
; It requires prior knowledge of how the Array and keys are structured.
; It is only feasible where there are a small number of possible keys.
; In this example, there are only 256 different values.
; It works well, for example, where the key is sex, department or state.
; It would be a disaster if the keys were name or phone number."
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

;----------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayItemize (arrArray, strDelimiter)
If !ArrInfo (arrArray, -1) Then Return "" ; No array.
If !ArrInfo (arrArray, 6) Then Return "" ; No elements.
If ArrInfo (arrArray, 0) > 1 Then Return "" ; Too much dimensions.
strItemList = ""
intHigh = Max (ArrInfo (arrArray, 1) - 1, 0)
intLow = 0
For intElem = intLow To intHigh
   If !!VarType (arrArray [intElem])
      strItemList = ItemInsert (arrArray [intElem], -1, strItemList, strDelimiter)
   Else
      strItemList = ItemInsert ("", -1, strItemList, strDelimiter)
   EndIf
Next
Return strItemList
;----------------------------------------------------------------------------------------------------------------------
; 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.
;----------------------------------------------------------------------------------------------------------------------
#EndFunction
;----------------------------------------------------------------------------------------------------------------------


; Test.

strMsgTitle = "Demo: udfArrayDistributionSort (arrArray)"
strMsgText = ""

strItemList = StrUpper (StrReplace (StrReplace (FileGet (IntControl (1004, 0, 0, 0, 0)), @CRLF, @LF), @CR, " ")) ; We use this script as test input.

strDelimiter = @LF
arrA = Arrayize (strItemList, strDelimiter)
arrB = Arrayize (strItemList, strDelimiter)

arrB = udfArrayDistributionSort (arrB, 0)

strMsgTextA = strMsgText : "Array A: " : @LF : udfArrayItemize (arrA, strDelimiter) : @LF : @LF
strMsgTextB = strMsgText : "Array B sorted: " : @LF : udfArrayItemize (arrB, strDelimiter) : @LF : @LF

strFilename = FileCreateTemp ("__A")
strFilenameA = strFilename : ".txt"
blnResult = FileRename (strFilename, strFilenameA)

strFilename = FileCreateTemp ("__B")
strFilenameB = strFilename : ".txt"
blnResult = FileRename (strFilename, strFilenameB)

intResult = FilePut (strFilenameA, StrReplace (strMsgTitle : @LF : strMsgTextA, @LF, @CRLF))
intResult = FilePut (strFilenameB, StrReplace (strMsgTitle : @LF : strMsgTextB, @LF, @CRLF))

blnResult = Run (strFilenameA, "")
blnResult = Run (strFilenameB, "")

blnResult = FileDelete (strFilenameA)
blnResult = FileDelete (strFilenameB)

Exit