udfArrayUnique
arr udfArrayUnique (arr, int, int)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfArrayUnique (arrArray, intSortMode, intSortDirection)
If !ArrInfo (arrArray, -1) Then Return ArrDimension (0) ; No array, return dim0 array with no element.
If ArrInfo (arrArray, 0) > 1 Then Return ArrDimension (0) ; Too much dimensions, return dim0 array with no element.
If !ArrInfo (arrArray, 6) Then Return ArrDimension (0) ; No elements, return dim0 array with no element.

strDelimiter = Num2Char (7) ; Surrogate, assuming that ASCII-7 'bell' control character does not occur in array data!

strItemList = ""
intListLow = 1
intListHigh = ArrInfo (arrArray, 1)
intArrLow = 0
intArrHigh = intListHigh - 1

For intElem = intArrLow To intArrHigh
   If !!VarType (arrArray [intElem])
      strItemList = strItemList : strDelimiter : arrArray [intElem]
   Else
      strItemList = strItemList : strDelimiter
   EndIf
Next
strItemList = StrSub (strItemList, 2, -1)

strListUnique = ""
For intElem = intListLow To intListHigh
   strItem = ItemExtract (intElem, strItemList, strDelimiter)
   If strItem != "" Then If !ItemLocate (strItem, strListUnique, strDelimiter) Then strListUnique = ItemInsert (strItem, -1, strListUnique, strDelimiter)
Next

Switch intSortMode
Case @SORTED
   Switch intSortDirection
   Case @ASCENDING
      strListUnique = ItemSort (strListUnique, strDelimiter)
      Break
   Case @DESCENDING
      strListUnique = ItemSort (strListUnique, strDelimiter)
      intListHigh = ItemCount (strListUnique, strDelimiter) - 1
      For intElem = intListHigh To intListLow By -1
         strListUnique = ItemRemove (intElem, ItemInsert (ItemExtract (intElem, strListUnique, strDelimiter), -1, strListUnique, strDelimiter), strDelimiter)
      Next
      Break
   EndSwitch
   Break
Case @UNSORTED
   Break
EndSwitch

Return Arrayize (strListUnique, strDelimiter)
;..........................................................................................................................................
; This UDF "udfArrayUnique" removes double entries from a given dim1 array and returns a new dim1 array.
; If the input array parameter does not fit to process, then the function returns a dim0 array with no element,
; which must be checked by the caller.
;
; intSortMode = @UNSORTED .......... Returns the unique array as is.
; intSortMode = @SORTED ............ Returns the unique array sorted.
; intSortDirection = @ASCENDING .... Performs an ascending 'word' sorting (using WinBatch function ItemSort).
; intSortDirection = @DESCENDING ... Performs a descending 'word' sorting (using WinBatch function ItemSort).
;
; Note:
; This UDF uses the ASCII-7 'bell' control character as a delimiter to build a temporary itemlist.
; Therefore make sure, that your array elements do not contain an ASCII-7 character,
; or define some other 'strange' ASCII character as delimiter.
;
; Detlev Dalitz.200200820.20090507.20090522.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

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

:Test1
arrArray = Arrayize ("zero,,one,two,zero,,,three,four,,,five,zero,six,one,seven,eigth,nine,one", ",")

strMsgText = strMsgText : "--- arrArray ---------" : @LF
intRowLow = 0
intRowHigh = ArrInfo (arrArray, 1) - 1
For intRow = intRowLow To intRowHigh
   strMsgText = strMsgText : arrArray [intRow] : @LF
Next
strMsgText = strMsgText : StrFill ("-", 50) : @LF


:Test2
arrArrayUnique = udfArrayUnique (arrArray, @UNSORTED, 0)

strMsgText = strMsgText : "--- arrArrayUnique --- unsorted ---" : @LF
intRowLow = 0
intRowHigh = ArrInfo (arrArrayUnique, 1) - 1
For intRow = intRowLow To intRowHigh
   strMsgText = strMsgText : arrArrayUnique [intRow] : @LF
Next
strMsgText = strMsgText : StrFill ("-", 50) : @LF

IntControl (28, 1, 0, 0, 0)
IntControl (63, 200, 100, 800, 900)
AskItemlist (strMsgTitle, strMsgText, @LF, @UNSORTED, @SINGLE)


:Test3
arrArrayUnique = udfArrayUnique (arrArray, @SORTED, @ASCENDING)

strMsgText = strMsgText : "--- arrArrayUnique --- sorted ascending ---" : @LF
intRowLow = 0
intRowHigh = ArrInfo (arrArrayUnique, 1) - 1
For intRow = intRowLow To intRowHigh
   strMsgText = strMsgText : arrArrayUnique [intRow] : @LF
Next
strMsgText = strMsgText : StrFill ("-", 50) : @LF

IntControl (28, 1, 0, 0, 0)
IntControl (63, 200, 100, 800, 900)
AskItemlist (strMsgTitle, strMsgText, @LF, @UNSORTED, @SINGLE)


:Test4
arrArrayUnique = udfArrayUnique (arrArray, @SORTED, @DESCENDING)

strMsgText = strMsgText : "--- arrArrayUnique --- sorted descending ---" : @LF
intRowLow = 0
intRowHigh = ArrInfo (arrArrayUnique, 1) - 1
For intRow = intRowLow To intRowHigh
   strMsgText = strMsgText : arrArrayUnique [intRow] : @LF
Next
strMsgText = strMsgText : StrFill ("-", 50) : @LF

IntControl (28, 1, 0, 0, 0)
IntControl (63, 200, 100, 800, 900)
AskItemlist (strMsgTitle, strMsgText, @LF, @UNSORTED, @SINGLE)

:CANCEL
Exit