123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124 |
- #include-Once
- #include "ArrayDisplayInternals.au3"
- #include "AutoItConstants.au3"
- #include "MsgBoxConstants.au3"
- #include "StringConstants.au3"
- ; #INDEX# =======================================================================================================================
- ; Title .........: Array
- ; AutoIt Version : 3.3.14.5
- ; Language ......: English
- ; Description ...: Functions for manipulating arrays.
- ; Author(s) .....: JdeB, Erik Pilsits, Ultima, Dale (Klaatu) Thompson, Cephas,randallc, Gary Frost, GEOSoft,
- ; Helias Gerassimou(hgeras), Brian Keene, Michael Michta, gcriaco, LazyCoder, Tylo, David Nuttall,
- ; Adam Moore (redndahead), SmOke_N, litlmike, Valik, Melba23
- ; ===============================================================================================================================
- ; #CURRENT# =====================================================================================================================
- ; _ArrayAdd
- ; _ArrayBinarySearch
- ; _ArrayColDelete
- ; _ArrayColInsert
- ; _ArrayCombinations
- ; _ArrayConcatenate
- ; _ArrayDelete
- ; _ArrayDisplay
- ; _ArrayExtract
- ; _ArrayFindAll
- ; _ArrayInsert
- ; _ArrayMax
- ; _ArrayMaxIndex
- ; _ArrayMin
- ; _ArrayMinIndex
- ; _ArrayPermute
- ; _ArrayPop
- ; _ArrayPush
- ; _ArrayReverse
- ; _ArraySearch
- ; _ArrayShuffle
- ; _ArraySort
- ; _ArraySwap
- ; _ArrayToClip
- ; _ArrayToString
- ; _ArrayTranspose
- ; _ArrayTrim
- ; _ArrayUnique
- ; _Array1DToHistogram
- ; ===============================================================================================================================
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; __Array_Combinations
- ; __Array_ExeterInternal
- ; __Array_GetNext
- ; __Array_GreaterThan
- ; __Array_LessThan
- ; __Array_MinMaxIndex
- ; __Array_StringRepeat
- ; __ArrayDualPivotSort
- ; __ArrayQuickSort1D
- ; __ArrayQuickSort2D
- ; __ArrayUnique_AutoErrFunc
- ; ===============================================================================================================================
- ; #GLOBAL CONSTANTS# ============================================================================================================
- Global Enum $ARRAYFILL_FORCE_DEFAULT, $ARRAYFILL_FORCE_SINGLEITEM, $ARRAYFILL_FORCE_INT, $ARRAYFILL_FORCE_NUMBER, _
- $ARRAYFILL_FORCE_PTR, $ARRAYFILL_FORCE_HWND, $ARRAYFILL_FORCE_STRING, $ARRAYFILL_FORCE_BOOLEAN
- Global Enum $ARRAYUNIQUE_NOCOUNT, $ARRAYUNIQUE_COUNT
- Global Enum $ARRAYUNIQUE_AUTO, $ARRAYUNIQUE_FORCE32, $ARRAYUNIQUE_FORCE64, $ARRAYUNIQUE_MATCH, $ARRAYUNIQUE_DISTINCT
- ; ===============================================================================================================================
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Jos
- ; Modified.......: Ultima - code cleanup; Melba23 - added 2D support & multiple addition
- ; ===============================================================================================================================
- Func _ArrayAdd(ByRef $aArray, $vValue, $iStart = 0, $sDelim_Item = "|", $sDelim_Row = @CRLF, $iForce = $ARRAYFILL_FORCE_DEFAULT)
- If $iStart = Default Then $iStart = 0
- If $sDelim_Item = Default Then $sDelim_Item = "|"
- If $sDelim_Row = Default Then $sDelim_Row = @CRLF
- If $iForce = Default Then $iForce = $ARRAYFILL_FORCE_DEFAULT
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
- Local $hDataType = 0
- Switch $iForce
- Case $ARRAYFILL_FORCE_INT
- $hDataType = Int
- Case $ARRAYFILL_FORCE_NUMBER
- $hDataType = Number
- Case $ARRAYFILL_FORCE_PTR
- $hDataType = Ptr
- Case $ARRAYFILL_FORCE_HWND
- $hDataType = Hwnd
- Case $ARRAYFILL_FORCE_STRING
- $hDataType = String
- Case $ARRAYFILL_FORCE_BOOLEAN
- $hDataType = "Boolean"
- EndSwitch
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $iForce = $ARRAYFILL_FORCE_SINGLEITEM Then
- ReDim $aArray[$iDim_1 + 1]
- $aArray[$iDim_1] = $vValue
- Return $iDim_1
- EndIf
- If IsArray($vValue) Then
- If UBound($vValue, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(5, 0, -1)
- $hDataType = 0
- Else
- Local $aTmp = StringSplit($vValue, $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- If UBound($aTmp, $UBOUND_ROWS) = 1 Then
- $aTmp[0] = $vValue
- EndIf
- $vValue = $aTmp
- EndIf
- Local $iAdd = UBound($vValue, $UBOUND_ROWS)
- ReDim $aArray[$iDim_1 + $iAdd]
- For $i = 0 To $iAdd - 1
- If String($hDataType) = "Boolean" Then
- Switch $vValue[$i]
- Case "True", "1"
- $aArray[$iDim_1 + $i] = True
- Case "False", "0", ""
- $aArray[$iDim_1 + $i] = False
- EndSwitch
- ElseIf IsFunc($hDataType) Then
- $aArray[$iDim_1 + $i] = $hDataType($vValue[$i])
- Else
- $aArray[$iDim_1 + $i] = $vValue[$i]
- EndIf
- Next
- Return $iDim_1 + $iAdd - 1
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
- If $iStart < 0 Or $iStart > $iDim_2 - 1 Then Return SetError(4, 0, -1)
- Local $iValDim_1, $iValDim_2 = 0, $iColCount
- If IsArray($vValue) Then
- If UBound($vValue, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(5, 0, -1)
- $iValDim_1 = UBound($vValue, $UBOUND_ROWS)
- $iValDim_2 = UBound($vValue, $UBOUND_COLUMNS)
- $hDataType = 0
- Else
- ; Convert string to 2D array
- Local $aSplit_1 = StringSplit($vValue, $sDelim_Row, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- $iValDim_1 = UBound($aSplit_1, $UBOUND_ROWS)
- Local $aTmp[$iValDim_1][0], $aSplit_2
- For $i = 0 To $iValDim_1 - 1
- $aSplit_2 = StringSplit($aSplit_1[$i], $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- $iColCount = UBound($aSplit_2)
- If $iColCount > $iValDim_2 Then
- ; Increase array size to fit max number of items on line
- $iValDim_2 = $iColCount
- ReDim $aTmp[$iValDim_1][$iValDim_2]
- EndIf
- For $j = 0 To $iColCount - 1
- $aTmp[$i][$j] = $aSplit_2[$j]
- Next
- Next
- $vValue = $aTmp
- EndIf
- ; Check if too many columns to fit
- If UBound($vValue, $UBOUND_COLUMNS) + $iStart > UBound($aArray, $UBOUND_COLUMNS) Then Return SetError(3, 0, -1)
- ReDim $aArray[$iDim_1 + $iValDim_1][$iDim_2]
- For $iWriteTo_Index = 0 To $iValDim_1 - 1
- For $j = 0 To $iDim_2 - 1
- If $j < $iStart Then
- $aArray[$iWriteTo_Index + $iDim_1][$j] = ""
- ElseIf $j - $iStart > $iValDim_2 - 1 Then
- $aArray[$iWriteTo_Index + $iDim_1][$j] = ""
- Else
- If String($hDataType) = "Boolean" Then
- Switch $vValue[$iWriteTo_Index][$j - $iStart]
- Case "True", "1"
- $aArray[$iWriteTo_Index + $iDim_1][$j] = True
- Case "False", "0", ""
- $aArray[$iWriteTo_Index + $iDim_1][$j] = False
- EndSwitch
- ElseIf IsFunc($hDataType) Then
- $aArray[$iWriteTo_Index + $iDim_1][$j] = $hDataType($vValue[$iWriteTo_Index][$j - $iStart])
- Else
- $aArray[$iWriteTo_Index + $iDim_1][$j] = $vValue[$iWriteTo_Index][$j - $iStart]
- EndIf
- EndIf
- Next
- Next
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return UBound($aArray, $UBOUND_ROWS) - 1
- EndFunc ;==>_ArrayAdd
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Jos
- ; Modified.......: Ultima - added $iEnd as parameter, code cleanup; Melba23 - added support for empty & 2D arrays
- ; ===============================================================================================================================
- Func _ArrayBinarySearch(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iColumn = 0)
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iColumn = Default Then $iColumn = 0
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- ; Bounds checking
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
- If $iDim_1 = 0 Then Return SetError(6, 0, -1)
- If $iEnd < 1 Or $iEnd > $iDim_1 - 1 Then $iEnd = $iDim_1 - 1
- If $iStart < 0 Then $iStart = 0
- If $iStart > $iEnd Then Return SetError(4, 0, -1)
- Local $iMid = Int(($iEnd + $iStart) / 2)
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $aArray[$iStart] > $vValue Or $aArray[$iEnd] < $vValue Then Return SetError(2, 0, -1)
- ; Search
- While $iStart <= $iMid And $vValue <> $aArray[$iMid]
- If $vValue < $aArray[$iMid] Then
- $iEnd = $iMid - 1
- Else
- $iStart = $iMid + 1
- EndIf
- $iMid = Int(($iEnd + $iStart) / 2)
- WEnd
- If $iStart > $iEnd Then Return SetError(3, 0, -1) ; Entry not found
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iColumn < 0 Or $iColumn > $iDim_2 Then Return SetError(7, 0, -1)
- If $aArray[$iStart][$iColumn] > $vValue Or $aArray[$iEnd][$iColumn] < $vValue Then Return SetError(2, 0, -1)
- ; Search
- While $iStart <= $iMid And $vValue <> $aArray[$iMid][$iColumn]
- If $vValue < $aArray[$iMid][$iColumn] Then
- $iEnd = $iMid - 1
- Else
- $iStart = $iMid + 1
- EndIf
- $iMid = Int(($iEnd + $iStart) / 2)
- WEnd
- If $iStart > $iEnd Then Return SetError(3, 0, -1) ; Entry not found
- Case Else
- Return SetError(5, 0, -1)
- EndSwitch
- Return $iMid
- EndFunc ;==>_ArrayBinarySearch
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Melba23
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayColDelete(ByRef $aArray, $iColumn, $bConvert = False)
- If $bConvert = Default Then $bConvert = False
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(2, 0, -1)
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
- Switch $iDim_2
- Case 2
- If $iColumn < 0 Or $iColumn > 1 Then Return SetError(3, 0, -1)
- If $bConvert Then
- Local $aTempArray[$iDim_1]
- For $i = 0 To $iDim_1 - 1
- $aTempArray[$i] = $aArray[$i][(Not $iColumn)]
- Next
- $aArray = $aTempArray
- Else
- ContinueCase
- EndIf
- Case Else
- If $iColumn < 0 Or $iColumn > $iDim_2 - 1 Then Return SetError(3, 0, -1)
- For $i = 0 To $iDim_1 - 1
- For $j = $iColumn To $iDim_2 - 2
- $aArray[$i][$j] = $aArray[$i][$j + 1]
- Next
- Next
- ReDim $aArray[$iDim_1][$iDim_2 - 1]
- EndSwitch
- Return UBound($aArray, $UBOUND_COLUMNS)
- EndFunc ;==>_ArrayColDelete
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Melba23
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayColInsert(ByRef $aArray, $iColumn)
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- Local $aTempArray[$iDim_1][2]
- Switch $iColumn
- Case 0, 1
- For $i = 0 To $iDim_1 - 1
- $aTempArray[$i][(Not $iColumn)] = $aArray[$i]
- Next
- Case Else
- Return SetError(3, 0, -1)
- EndSwitch
- $aArray = $aTempArray
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
- If $iColumn < 0 Or $iColumn > $iDim_2 Then Return SetError(3, 0, -1)
- ReDim $aArray[$iDim_1][$iDim_2 + 1]
- For $i = 0 To $iDim_1 - 1
- For $j = $iDim_2 To $iColumn + 1 Step -1
- $aArray[$i][$j] = $aArray[$i][$j - 1]
- Next
- $aArray[$i][$iColumn] = ""
- Next
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return UBound($aArray, $UBOUND_COLUMNS)
- EndFunc ;==>_ArrayColInsert
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Erik Pilsits
- ; Modified.......: 07/08/2008
- ; ===============================================================================================================================
- Func _ArrayCombinations(Const ByRef $aArray, $iSet, $sDelimiter = "")
- If $sDelimiter = Default Then $sDelimiter = ""
- If Not IsArray($aArray) Then Return SetError(1, 0, 0)
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, 0)
- Local $iN = UBound($aArray)
- Local $iR = $iSet
- Local $aIdx[$iR]
- For $i = 0 To $iR - 1
- $aIdx[$i] = $i
- Next
- Local $iTotal = __Array_Combinations($iN, $iR)
- Local $iLeft = $iTotal
- Local $aResult[$iTotal + 1]
- $aResult[0] = $iTotal
- Local $iCount = 1
- While $iLeft > 0
- __Array_GetNext($iN, $iR, $iLeft, $iTotal, $aIdx)
- For $i = 0 To $iSet - 1
- $aResult[$iCount] &= $aArray[$aIdx[$i]] & $sDelimiter
- Next
- If $sDelimiter <> "" Then $aResult[$iCount] = StringTrimRight($aResult[$iCount], 1)
- $iCount += 1
- WEnd
- Return $aResult
- EndFunc ;==>_ArrayCombinations
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Ultima
- ; Modified.......: Partypooper - added target start index; Melba23 - add 2D support
- ; ===============================================================================================================================
- Func _ArrayConcatenate(ByRef $aArrayTarget, Const ByRef $aArraySource, $iStart = 0)
- If $iStart = Default Then $iStart = 0
- If Not IsArray($aArrayTarget) Then Return SetError(1, 0, -1)
- If Not IsArray($aArraySource) Then Return SetError(2, 0, -1)
- Local $iDim_Total_Tgt = UBound($aArrayTarget, $UBOUND_DIMENSIONS)
- Local $iDim_Total_Src = UBound($aArraySource, $UBOUND_DIMENSIONS)
- Local $iDim_1_Tgt = UBound($aArrayTarget, $UBOUND_ROWS)
- Local $iDim_1_Src = UBound($aArraySource, $UBOUND_ROWS)
- If $iStart < 0 Or $iStart > $iDim_1_Src - 1 Then Return SetError(6, 0, -1)
- Switch $iDim_Total_Tgt
- Case 1
- If $iDim_Total_Src <> 1 Then Return SetError(4, 0, -1)
- ReDim $aArrayTarget[$iDim_1_Tgt + $iDim_1_Src - $iStart]
- For $i = $iStart To $iDim_1_Src - 1
- $aArrayTarget[$iDim_1_Tgt + $i - $iStart] = $aArraySource[$i]
- Next
- Case 2
- If $iDim_Total_Src <> 2 Then Return SetError(4, 0, -1)
- Local $iDim_2_Tgt = UBound($aArrayTarget, $UBOUND_COLUMNS)
- If UBound($aArraySource, $UBOUND_COLUMNS) <> $iDim_2_Tgt Then Return SetError(5, 0, -1)
- ReDim $aArrayTarget[$iDim_1_Tgt + $iDim_1_Src - $iStart][$iDim_2_Tgt]
- For $i = $iStart To $iDim_1_Src - 1
- For $j = 0 To $iDim_2_Tgt - 1
- $aArrayTarget[$iDim_1_Tgt + $i - $iStart][$j] = $aArraySource[$i][$j]
- Next
- Next
- Case Else
- Return SetError(3, 0, -1)
- EndSwitch
- Return UBound($aArrayTarget, $UBOUND_ROWS)
- EndFunc ;==>_ArrayConcatenate
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - array passed ByRef, jaberwocky6669, Melba23 - added 2D support & multiple deletion
- ; ===============================================================================================================================
- Func _ArrayDelete(ByRef $aArray, $vRange)
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- If IsArray($vRange) Then
- If UBound($vRange, $UBOUND_DIMENSIONS) <> 1 Or UBound($vRange, $UBOUND_ROWS) < 2 Then Return SetError(4, 0, -1)
- Else
- ; Expand range
- Local $iNumber, $aSplit_1, $aSplit_2
- $vRange = StringStripWS($vRange, 8)
- $aSplit_1 = StringSplit($vRange, ";")
- $vRange = ""
- For $i = 1 To $aSplit_1[0]
- ; Check for correct range syntax
- If Not StringRegExp($aSplit_1[$i], "^\d+(-\d+)?$") Then Return SetError(3, 0, -1)
- $aSplit_2 = StringSplit($aSplit_1[$i], "-")
- Switch $aSplit_2[0]
- Case 1
- $vRange &= $aSplit_2[1] & ";"
- Case 2
- If Number($aSplit_2[2]) >= Number($aSplit_2[1]) Then
- $iNumber = $aSplit_2[1] - 1
- Do
- $iNumber += 1
- $vRange &= $iNumber & ";"
- Until $iNumber = $aSplit_2[2]
- EndIf
- EndSwitch
- Next
- $vRange = StringSplit(StringTrimRight($vRange, 1), ";")
- EndIf
- If $vRange[1] < 0 Or $vRange[$vRange[0]] > $iDim_1 Then Return SetError(5, 0, -1)
- ; Remove rows
- Local $iCopyTo_Index = 0
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- ; Loop through array flagging elements to be deleted
- For $i = 1 To $vRange[0]
- $aArray[$vRange[$i]] = ChrW(0xFAB1)
- Next
- ; Now copy rows to keep to fill deleted rows
- For $iReadFrom_Index = 0 To $iDim_1
- If $aArray[$iReadFrom_Index] == ChrW(0xFAB1) Then
- ContinueLoop
- Else
- If $iReadFrom_Index <> $iCopyTo_Index Then
- $aArray[$iCopyTo_Index] = $aArray[$iReadFrom_Index]
- EndIf
- $iCopyTo_Index += 1
- EndIf
- Next
- ReDim $aArray[$iDim_1 - $vRange[0] + 1]
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- ; Loop through array flagging elements to be deleted
- For $i = 1 To $vRange[0]
- $aArray[$vRange[$i]][0] = ChrW(0xFAB1)
- Next
- ; Now copy rows to keep to fill deleted rows
- For $iReadFrom_Index = 0 To $iDim_1
- If $aArray[$iReadFrom_Index][0] == ChrW(0xFAB1) Then
- ContinueLoop
- Else
- If $iReadFrom_Index <> $iCopyTo_Index Then
- For $j = 0 To $iDim_2
- $aArray[$iCopyTo_Index][$j] = $aArray[$iReadFrom_Index][$j]
- Next
- EndIf
- $iCopyTo_Index += 1
- EndIf
- Next
- ReDim $aArray[$iDim_1 - $vRange[0] + 1][$iDim_2 + 1]
- Case Else
- Return SetError(2, 0, False)
- EndSwitch
- Return UBound($aArray, $UBOUND_ROWS)
- EndFunc ;==>_ArrayDelete
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: randallc, Ultima
- ; Modified.......: Gary Frost (gafrost), Ultima, Zedna, jpm, Melba23, AZJIO, UEZ
- ; ===============================================================================================================================
- Func _ArrayDisplay(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default)
- #forceref $vUser_Separator
- Local $iRet = __ArrayDisplay_Share($aArray, $sTitle, $sArrayRange, $iFlags, Default, $sHeader, $iMax_ColWidth, 0, False)
- Return SetError(@error, @extended, $iRet)
- EndFunc ;==>_ArrayDisplay
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Melba23
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayExtract(Const ByRef $aArray, $iStart_Row = -1, $iEnd_Row = -1, $iStart_Col = -1, $iEnd_Col = -1)
- If $iStart_Row = Default Then $iStart_Row = -1
- If $iEnd_Row = Default Then $iEnd_Row = -1
- If $iStart_Col = Default Then $iStart_Col = -1
- If $iEnd_Col = Default Then $iEnd_Col = -1
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- If $iEnd_Row = -1 Then $iEnd_Row = $iDim_1
- If $iStart_Row = -1 Then $iStart_Row = 0
- If $iStart_Row < -1 Or $iEnd_Row < -1 Then Return SetError(3, 0, -1)
- If $iStart_Row > $iDim_1 Or $iEnd_Row > $iDim_1 Then Return SetError(3, 0, -1)
- If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- Local $aRetArray[$iEnd_Row - $iStart_Row + 1]
- For $i = 0 To $iEnd_Row - $iStart_Row
- $aRetArray[$i] = $aArray[$i + $iStart_Row]
- Next
- Return $aRetArray
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iEnd_Col = -1 Then $iEnd_Col = $iDim_2
- If $iStart_Col = -1 Then $iStart_Col = 0
- If $iStart_Col < -1 Or $iEnd_Col < -1 Then Return SetError(5, 0, -1)
- If $iStart_Col > $iDim_2 Or $iEnd_Col > $iDim_2 Then Return SetError(5, 0, -1)
- If $iStart_Col > $iEnd_Col Then Return SetError(6, 0, -1)
- If $iStart_Col = $iEnd_Col Then
- Local $aRetArray[$iEnd_Row - $iStart_Row + 1]
- Else
- Local $aRetArray[$iEnd_Row - $iStart_Row + 1][$iEnd_Col - $iStart_Col + 1]
- EndIf
- For $i = 0 To $iEnd_Row - $iStart_Row
- For $j = 0 To $iEnd_Col - $iStart_Col
- If $iStart_Col = $iEnd_Col Then
- $aRetArray[$i] = $aArray[$i + $iStart_Row][$j + $iStart_Col]
- Else
- $aRetArray[$i][$j] = $aArray[$i + $iStart_Row][$j + $iStart_Col]
- EndIf
- Next
- Next
- Return $aRetArray
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return 1
- EndFunc ;==>_ArrayExtract
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: GEOSoft, Ultima
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayFindAll(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iSubItem = 0, $bRow = False)
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iCase = Default Then $iCase = 0
- If $iCompare = Default Then $iCompare = 0
- If $iSubItem = Default Then $iSubItem = 0
- If $bRow = Default Then $bRow = False
- $iStart = _ArraySearch($aArray, $vValue, $iStart, $iEnd, $iCase, $iCompare, 1, $iSubItem, $bRow)
- If @error Then Return SetError(@error, 0, -1)
- Local $iIndex = 0, $avResult[UBound($aArray, ($bRow ? $UBOUND_COLUMNS : $UBOUND_ROWS))] ; Set dimension for Column/Row
- Do
- $avResult[$iIndex] = $iStart
- $iIndex += 1
- $iStart = _ArraySearch($aArray, $vValue, $iStart + 1, $iEnd, $iCase, $iCompare, 1, $iSubItem, $bRow)
- Until @error
- ReDim $avResult[$iIndex]
- Return $avResult
- EndFunc ;==>_ArrayFindAll
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Jos
- ; Modified.......: Ultima - code cleanup; Melba23 - element position check, 2D support & multiple insertions
- ; ===============================================================================================================================
- Func _ArrayInsert(ByRef $aArray, $vRange, $vValue = "", $iStart = 0, $sDelim_Item = "|", $sDelim_Row = @CRLF, $iForce = $ARRAYFILL_FORCE_DEFAULT)
- If $vValue = Default Then $vValue = ""
- If $iStart = Default Then $iStart = 0
- If $sDelim_Item = Default Then $sDelim_Item = "|"
- If $sDelim_Row = Default Then $sDelim_Row = @CRLF
- If $iForce = Default Then $iForce = $ARRAYFILL_FORCE_DEFAULT
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- Local $hDataType = 0
- Switch $iForce
- Case $ARRAYFILL_FORCE_INT
- $hDataType = Int
- Case $ARRAYFILL_FORCE_NUMBER
- $hDataType = Number
- Case $ARRAYFILL_FORCE_PTR
- $hDataType = Ptr
- Case $ARRAYFILL_FORCE_HWND
- $hDataType = Hwnd
- Case $ARRAYFILL_FORCE_STRING
- $hDataType = String
- EndSwitch
- Local $aSplit_1, $aSplit_2
- If IsArray($vRange) Then
- If UBound($vRange, $UBOUND_DIMENSIONS) <> 1 Or UBound($vRange, $UBOUND_ROWS) < 2 Then Return SetError(4, 0, -1)
- Else
- ; Expand range
- Local $iNumber
- $vRange = StringStripWS($vRange, 8)
- $aSplit_1 = StringSplit($vRange, ";")
- $vRange = ""
- For $i = 1 To $aSplit_1[0]
- ; Check for correct range syntax
- If Not StringRegExp($aSplit_1[$i], "^\d+(-\d+)?$") Then Return SetError(3, 0, -1)
- $aSplit_2 = StringSplit($aSplit_1[$i], "-")
- Switch $aSplit_2[0]
- Case 1
- $vRange &= $aSplit_2[1] & ";"
- Case 2
- If Number($aSplit_2[2]) >= Number($aSplit_2[1]) Then
- $iNumber = $aSplit_2[1] - 1
- Do
- $iNumber += 1
- $vRange &= $iNumber & ";"
- Until $iNumber = $aSplit_2[2]
- EndIf
- EndSwitch
- Next
- $vRange = StringSplit(StringTrimRight($vRange, 1), ";")
- EndIf
- If $vRange[1] < 0 Or $vRange[$vRange[0]] > $iDim_1 Then Return SetError(5, 0, -1)
- For $i = 2 To $vRange[0]
- If $vRange[$i] < $vRange[$i - 1] Then Return SetError(3, 0, -1)
- Next
- Local $iCopyTo_Index = $iDim_1 + $vRange[0]
- Local $iInsertPoint_Index = $vRange[0]
- ; Get lowest insert point
- Local $iInsert_Index = $vRange[$iInsertPoint_Index]
- ; Insert lines
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $iForce = $ARRAYFILL_FORCE_SINGLEITEM Then
- ReDim $aArray[$iDim_1 + $vRange[0] + 1]
- For $iReadFromIndex = $iDim_1 To 0 Step -1
- ; Copy existing elements
- $aArray[$iCopyTo_Index] = $aArray[$iReadFromIndex]
- ; Move up array
- $iCopyTo_Index -= 1
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- While $iReadFromIndex = $iInsert_Index
- ; Insert new item
- $aArray[$iCopyTo_Index] = $vValue
- ; Move up array
- $iCopyTo_Index -= 1
- ; Reset insert index
- $iInsertPoint_Index -= 1
- If $iInsertPoint_Index < 1 Then ExitLoop 2
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- WEnd
- Next
- Return $iDim_1 + $vRange[0] + 1
- EndIf
- ReDim $aArray[$iDim_1 + $vRange[0] + 1]
- If IsArray($vValue) Then
- If UBound($vValue, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(5, 0, -1)
- $hDataType = 0
- Else
- Local $aTmp = StringSplit($vValue, $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- If UBound($aTmp, $UBOUND_ROWS) = 1 Then
- $aTmp[0] = $vValue
- $hDataType = 0
- EndIf
- $vValue = $aTmp
- EndIf
- For $iReadFromIndex = $iDim_1 To 0 Step -1
- ; Copy existing elements
- $aArray[$iCopyTo_Index] = $aArray[$iReadFromIndex]
- ; Move up array
- $iCopyTo_Index -= 1
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- While $iReadFromIndex = $iInsert_Index
- ; Insert new item
- If $iInsertPoint_Index <= UBound($vValue, $UBOUND_ROWS) Then
- If IsFunc($hDataType) Then
- $aArray[$iCopyTo_Index] = $hDataType($vValue[$iInsertPoint_Index - 1])
- Else
- $aArray[$iCopyTo_Index] = $vValue[$iInsertPoint_Index - 1]
- EndIf
- Else
- $aArray[$iCopyTo_Index] = ""
- EndIf
- ; Move up array
- $iCopyTo_Index -= 1
- ; Reset insert index
- $iInsertPoint_Index -= 1
- If $iInsertPoint_Index = 0 Then ExitLoop 2
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- WEnd
- Next
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
- If $iStart < 0 Or $iStart > $iDim_2 - 1 Then Return SetError(6, 0, -1)
- Local $iValDim_1, $iValDim_2
- If IsArray($vValue) Then
- If UBound($vValue, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(7, 0, -1)
- $iValDim_1 = UBound($vValue, $UBOUND_ROWS)
- $iValDim_2 = UBound($vValue, $UBOUND_COLUMNS)
- $hDataType = 0
- Else
- ; Convert string to 2D array
- $aSplit_1 = StringSplit($vValue, $sDelim_Row, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- $iValDim_1 = UBound($aSplit_1, $UBOUND_ROWS)
- StringReplace($aSplit_1[0], $sDelim_Item, "")
- $iValDim_2 = @extended + 1
- Local $aTmp[$iValDim_1][$iValDim_2]
- For $i = 0 To $iValDim_1 - 1
- $aSplit_2 = StringSplit($aSplit_1[$i], $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
- For $j = 0 To $iValDim_2 - 1
- $aTmp[$i][$j] = $aSplit_2[$j]
- Next
- Next
- $vValue = $aTmp
- EndIf
- ; Check if too many columns to fit
- If UBound($vValue, $UBOUND_COLUMNS) + $iStart > UBound($aArray, $UBOUND_COLUMNS) Then Return SetError(8, 0, -1)
- ReDim $aArray[$iDim_1 + $vRange[0] + 1][$iDim_2]
- For $iReadFromIndex = $iDim_1 To 0 Step -1
- ; Copy existing elements
- For $j = 0 To $iDim_2 - 1
- $aArray[$iCopyTo_Index][$j] = $aArray[$iReadFromIndex][$j]
- Next
- ; Move up array
- $iCopyTo_Index -= 1
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- While $iReadFromIndex = $iInsert_Index
- ; Insert new item
- For $j = 0 To $iDim_2 - 1
- If $j < $iStart Then
- $aArray[$iCopyTo_Index][$j] = ""
- ElseIf $j - $iStart > $iValDim_2 - 1 Then
- $aArray[$iCopyTo_Index][$j] = ""
- Else
- If $iInsertPoint_Index - 1 < $iValDim_1 Then
- If IsFunc($hDataType) Then
- $aArray[$iCopyTo_Index][$j] = $hDataType($vValue[$iInsertPoint_Index - 1][$j - $iStart])
- Else
- $aArray[$iCopyTo_Index][$j] = $vValue[$iInsertPoint_Index - 1][$j - $iStart]
- EndIf
- Else
- $aArray[$iCopyTo_Index][$j] = ""
- EndIf
- EndIf
- Next
- ; Move up array
- $iCopyTo_Index -= 1
- ; Reset insert index
- $iInsertPoint_Index -= 1
- If $iInsertPoint_Index = 0 Then ExitLoop 2
- ; Get next insert point
- $iInsert_Index = $vRange[$iInsertPoint_Index]
- WEnd
- Next
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return UBound($aArray, $UBOUND_ROWS)
- EndFunc ;==>_ArrayInsert
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic, Ultima - added $iEnd parameter, code cleanup; Melba23 - Added 2D support
- ; ===============================================================================================================================
- Func _ArrayMax(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
- Local $iResult = _ArrayMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem)
- If @error Then Return SetError(@error, 0, "")
- If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then
- Return $aArray[$iResult]
- Else
- Return $aArray[$iResult][$iSubItem]
- EndIf
- EndFunc ;==>_ArrayMax
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic; Melba23 - Added 2D support; guinness - Reduced duplicate code.
- ; ===============================================================================================================================
- Func _ArrayMaxIndex(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
- If $iCompNumeric = Default Then $iCompNumeric = 0
- If $iStart = Default Then $iStart = -1
- If $iEnd = Default Then $iEnd = -1
- If $iSubItem = Default Then $iSubItem = 0
- Local $iRet = __Array_MinMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem, __Array_GreaterThan) ; Pass a delegate function to check if value1 > value2.
- Return SetError(@error, 0, $iRet)
- EndFunc ;==>_ArrayMaxIndex
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic, Ultima - added $iEnd parameter, code cleanup; Melba23 - Added 2D support
- ; ===============================================================================================================================
- Func _ArrayMin(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
- Local $iResult = _ArrayMinIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem)
- If @error Then Return SetError(@error, 0, "")
- If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then
- Return $aArray[$iResult]
- Else
- Return $aArray[$iResult][$iSubItem]
- EndIf
- EndFunc ;==>_ArrayMin
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic; Melba23 - Added 2D support; guinness - Reduced duplicate code.
- ; ===============================================================================================================================
- Func _ArrayMinIndex(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
- If $iCompNumeric = Default Then $iCompNumeric = 0
- If $iStart = Default Then $iStart = -1
- If $iEnd = Default Then $iEnd = -1
- If $iSubItem = Default Then $iSubItem = 0
- Local $iRet = __Array_MinMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem, __Array_LessThan) ; Pass a delegate function to check if value1 < value2.
- Return SetError(@error, 0, $iRet)
- EndFunc ;==>_ArrayMinIndex
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Erik Pilsits
- ; Modified.......: Melba23 - added support for empty arrays
- ; ===============================================================================================================================
- Func _ArrayPermute(ByRef $aArray, $sDelimiter = "")
- If $sDelimiter = Default Then $sDelimiter = ""
- If Not IsArray($aArray) Then Return SetError(1, 0, 0)
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, 0)
- Local $iSize = UBound($aArray), $iFactorial = 1, $aIdx[$iSize], $aResult[1], $iCount = 1
- If UBound($aArray) Then
- For $i = 0 To $iSize - 1
- $aIdx[$i] = $i
- Next
- For $i = $iSize To 1 Step -1
- $iFactorial *= $i
- Next
- ReDim $aResult[$iFactorial + 1]
- $aResult[0] = $iFactorial
- __Array_ExeterInternal($aArray, 0, $iSize, $sDelimiter, $aIdx, $aResult, $iCount)
- Else
- $aResult[0] = 0
- EndIf
- Return $aResult
- EndFunc ;==>_ArrayPermute
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Ultima - code cleanup; Melba23 - added support for empty arrays
- ; ===============================================================================================================================
- Func _ArrayPop(ByRef $aArray)
- If (Not IsArray($aArray)) Then Return SetError(1, 0, "")
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, "")
- Local $iUBound = UBound($aArray) - 1
- If $iUBound = -1 Then Return SetError(3, 0, "")
- Local $sLastVal = $aArray[$iUBound]
- ; Remove last item
- If $iUBound > -1 Then
- ReDim $aArray[$iUBound]
- EndIf
- ; Return last item
- Return $sLastVal
- EndFunc ;==>_ArrayPop
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Helias Gerassimou(hgeras), Ultima - code cleanup/rewrite (major optimization), fixed support for $vValue as an array
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayPush(ByRef $aArray, $vValue, $iDirection = 0)
- If $iDirection = Default Then $iDirection = 0
- If (Not IsArray($aArray)) Then Return SetError(1, 0, 0)
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(3, 0, 0)
- Local $iUBound = UBound($aArray) - 1
- If IsArray($vValue) Then ; $vValue is an array
- Local $iUBoundS = UBound($vValue)
- If ($iUBoundS - 1) > $iUBound Then Return SetError(2, 0, 0)
- ; $vValue is an array smaller than $aArray
- If $iDirection Then ; slide right, add to front
- For $i = $iUBound To $iUBoundS Step -1
- $aArray[$i] = $aArray[$i - $iUBoundS]
- Next
- For $i = 0 To $iUBoundS - 1
- $aArray[$i] = $vValue[$i]
- Next
- Else ; slide left, add to end
- For $i = 0 To $iUBound - $iUBoundS
- $aArray[$i] = $aArray[$i + $iUBoundS]
- Next
- For $i = 0 To $iUBoundS - 1
- $aArray[$i + $iUBound - $iUBoundS + 1] = $vValue[$i]
- Next
- EndIf
- Else
- ; Check for empty array
- If $iUBound > -1 Then
- If $iDirection Then ; slide right, add to front
- For $i = $iUBound To 1 Step -1
- $aArray[$i] = $aArray[$i - 1]
- Next
- $aArray[0] = $vValue
- Else ; slide left, add to end
- For $i = 0 To $iUBound - 1
- $aArray[$i] = $aArray[$i + 1]
- Next
- $aArray[$iUBound] = $vValue
- EndIf
- EndIf
- EndIf
- Return 1
- EndFunc ;==>_ArrayPush
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Brian Keene
- ; Modified.......: Jos - added $iStart parameter and logic; Tylo - added $iEnd parameter and rewrote it for speed
- ; ===============================================================================================================================
- Func _ArrayReverse(ByRef $aArray, $iStart = 0, $iEnd = 0)
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If Not IsArray($aArray) Then Return SetError(1, 0, 0)
- If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(3, 0, 0)
- If Not UBound($aArray) Then Return SetError(4, 0, 0)
- Local $vTmp, $iUBound = UBound($aArray) - 1
- ; Bounds checking
- If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
- If $iStart < 0 Then $iStart = 0
- If $iStart > $iEnd Then Return SetError(2, 0, 0)
- ; Reverse
- For $i = $iStart To Int(($iStart + $iEnd - 1) / 2)
- $vTmp = $aArray[$i]
- $aArray[$i] = $aArray[$iEnd]
- $aArray[$iEnd] = $vTmp
- $iEnd -= 1
- Next
- Return 1
- EndFunc ;==>_ArrayReverse
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Michael Michta <MetalGX91 at GMail dot com>
- ; Modified.......: gcriaco <gcriaco at gmail dot com>; Ultima - 2D arrays supported, directional search, code cleanup, optimization; Melba23 - added support for empty arrays and row search; BrunoJ - Added compare option 3 to use a regex pattern
- ; ===============================================================================================================================
- Func _ArraySearch(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iForward = 1, $iSubItem = -1, $bRow = False)
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iCase = Default Then $iCase = 0
- If $iCompare = Default Then $iCompare = 0
- If $iForward = Default Then $iForward = 1
- If $iSubItem = Default Then $iSubItem = -1
- If $bRow = Default Then $bRow = False
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray) - 1
- If $iDim_1 = -1 Then Return SetError(3, 0, -1)
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- ; Same var Type of comparison
- Local $bCompType = False
- If $iCompare = 2 Then
- $iCompare = 0
- $bCompType = True
- EndIf
- ; Bounds checking
- If $bRow Then
- If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then Return SetError(5, 0, -1)
- If $iEnd < 1 Or $iEnd > $iDim_2 Then $iEnd = $iDim_2
- If $iStart < 0 Then $iStart = 0
- If $iStart > $iEnd Then Return SetError(4, 0, -1)
- Else
- If $iEnd < 1 Or $iEnd > $iDim_1 Then $iEnd = $iDim_1
- If $iStart < 0 Then $iStart = 0
- If $iStart > $iEnd Then Return SetError(4, 0, -1)
- EndIf
- ; Direction (flip if $iForward = 0)
- Local $iStep = 1
- If Not $iForward Then
- Local $iTmp = $iStart
- $iStart = $iEnd
- $iEnd = $iTmp
- $iStep = -1
- EndIf
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1 ; 1D array search
- If Not $iCompare Then
- If Not $iCase Then
- For $i = $iStart To $iEnd Step $iStep
- If $bCompType And VarGetType($aArray[$i]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$i] = $vValue Then Return $i
- Next
- Else
- For $i = $iStart To $iEnd Step $iStep
- If $bCompType And VarGetType($aArray[$i]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$i] == $vValue Then Return $i
- Next
- EndIf
- Else
- For $i = $iStart To $iEnd Step $iStep
- If $iCompare = 3 Then
- If StringRegExp($aArray[$i], $vValue) Then Return $i
- Else
- If StringInStr($aArray[$i], $vValue, $iCase) > 0 Then Return $i
- EndIf
- Next
- EndIf
- Case 2 ; 2D array search
- Local $iDim_Sub
- If $bRow Then
- ; Search rows
- $iDim_Sub = $iDim_1
- If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
- If $iSubItem < 0 Then
- ; will search for all Col
- $iSubItem = 0
- Else
- $iDim_Sub = $iSubItem
- EndIf
- Else
- ; Search columns
- $iDim_Sub = $iDim_2
- If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
- If $iSubItem < 0 Then
- ; will search for all Col
- $iSubItem = 0
- Else
- $iDim_Sub = $iSubItem
- EndIf
- EndIf
- ; Now do the search
- For $j = $iSubItem To $iDim_Sub
- If Not $iCompare Then
- If Not $iCase Then
- For $i = $iStart To $iEnd Step $iStep
- If $bRow Then
- If $bCompType And VarGetType($aArray[$j][$i]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$j][$i] = $vValue Then Return $i
- Else
- If $bCompType And VarGetType($aArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$i][$j] = $vValue Then Return $i
- EndIf
- Next
- Else
- For $i = $iStart To $iEnd Step $iStep
- If $bRow Then
- If $bCompType And VarGetType($aArray[$j][$i]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$j][$i] == $vValue Then Return $i
- Else
- If $bCompType And VarGetType($aArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
- If $aArray[$i][$j] == $vValue Then Return $i
- EndIf
- Next
- EndIf
- Else
- For $i = $iStart To $iEnd Step $iStep
- If $iCompare = 3 Then
- If $bRow Then
- If StringRegExp($aArray[$j][$i], $vValue) Then Return $i
- Else
- If StringRegExp($aArray[$i][$j], $vValue) Then Return $i
- EndIf
- Else
- If $bRow Then
- If StringInStr($aArray[$j][$i], $vValue, $iCase) > 0 Then Return $i
- Else
- If StringInStr($aArray[$i][$j], $vValue, $iCase) > 0 Then Return $i
- EndIf
- EndIf
- Next
- EndIf
- Next
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return SetError(6, 0, -1)
- EndFunc ;==>_ArraySearch
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Melba23
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArrayShuffle(ByRef $aArray, $iStart_Row = 0, $iEnd_Row = 0, $iCol = -1)
- ; Fisher–Yates algorithm
- If $iStart_Row = Default Then $iStart_Row = 0
- If $iEnd_Row = Default Then $iEnd_Row = 0
- If $iCol = Default Then $iCol = -1
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
- If $iEnd_Row = 0 Then $iEnd_Row = $iDim_1 - 1
- If $iStart_Row < 0 Or $iStart_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
- If $iEnd_Row < 1 Or $iEnd_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
- If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
- Local $vTmp, $iRand
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- For $i = $iEnd_Row To $iStart_Row + 1 Step -1
- $iRand = Random($iStart_Row, $i, 1)
- $vTmp = $aArray[$i]
- $aArray[$i] = $aArray[$iRand]
- $aArray[$iRand] = $vTmp
- Next
- Return 1
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
- If $iCol < -1 Or $iCol > $iDim_2 - 1 Then Return SetError(5, 0, -1)
- Local $iCol_Start, $iCol_End
- If $iCol = -1 Then
- $iCol_Start = 0
- $iCol_End = $iDim_2 - 1
- Else
- $iCol_Start = $iCol
- $iCol_End = $iCol
- EndIf
- For $i = $iEnd_Row To $iStart_Row + 1 Step -1
- $iRand = Random($iStart_Row, $i, 1)
- For $j = $iCol_Start To $iCol_End
- $vTmp = $aArray[$i][$j]
- $aArray[$i][$j] = $aArray[$iRand][$j]
- $aArray[$iRand][$j] = $vTmp
- Next
- Next
- Return 1
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- EndFunc ;==>_ArrayShuffle
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Jos
- ; Modified.......: LazyCoder - added $iSubItem option; Tylo - implemented stable QuickSort algo; Jos - changed logic to correctly Sort arrays with mixed Values and Strings; Melba23 - implemented stable pivot algo
- ; ===============================================================================================================================
- Func _ArraySort(ByRef $aArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iPivot = 0)
- If $iDescending = Default Then $iDescending = 0
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iSubItem = Default Then $iSubItem = 0
- If $iPivot = Default Then $iPivot = 0
- If Not IsArray($aArray) Then Return SetError(1, 0, 0)
- Local $iUBound = UBound($aArray) - 1
- If $iUBound = -1 Then Return SetError(5, 0, 0)
- ; Bounds checking
- If $iEnd = Default Then $iEnd = 0
- If $iEnd < 1 Or $iEnd > $iUBound Or $iEnd = Default Then $iEnd = $iUBound
- If $iStart < 0 Or $iStart = Default Then $iStart = 0
- If $iStart > $iEnd Then Return SetError(2, 0, 0)
- ; Sort
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $iPivot Then ; Switch algorithms as required
- __ArrayDualPivotSort($aArray, $iStart, $iEnd)
- Else
- __ArrayQuickSort1D($aArray, $iStart, $iEnd)
- EndIf
- If $iDescending Then _ArrayReverse($aArray, $iStart, $iEnd)
- Case 2
- If $iPivot Then Return SetError(6, 0, 0) ; Error if 2D array and $iPivot
- Local $iSubMax = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iSubItem > $iSubMax Then Return SetError(3, 0, 0)
- If $iDescending Then
- $iDescending = -1
- Else
- $iDescending = 1
- EndIf
- __ArrayQuickSort2D($aArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax)
- Case Else
- Return SetError(4, 0, 0)
- EndSwitch
- Return 1
- EndFunc ;==>_ArraySort
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __ArrayQuickSort1D
- ; Description ...: Helper function for sorting 1D arrays
- ; Syntax.........: __ArrayQuickSort1D ( ByRef $aArray, ByRef $iStart, ByRef $iEnd )
- ; Parameters ....: $aArray - Array to sort
- ; $iStart - Index of array to start sorting at
- ; $iEnd - Index of array to stop sorting at
- ; Return values .: None
- ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
- ; Modified.......:
- ; Remarks .......: For Internal Use Only
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __ArrayQuickSort1D(ByRef $aArray, Const ByRef $iStart, Const ByRef $iEnd)
- If $iEnd <= $iStart Then Return
- Local $vTmp
- ; InsertionSort (faster for smaller segments)
- If ($iEnd - $iStart) < 15 Then
- Local $vCur
- For $i = $iStart + 1 To $iEnd
- $vTmp = $aArray[$i]
- If IsNumber($vTmp) Then
- For $j = $i - 1 To $iStart Step -1
- $vCur = $aArray[$j]
- ; If $vTmp >= $vCur Then ExitLoop
- If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop
- $aArray[$j + 1] = $vCur
- Next
- Else
- For $j = $i - 1 To $iStart Step -1
- If (StringCompare($vTmp, $aArray[$j]) >= 0) Then ExitLoop
- $aArray[$j + 1] = $aArray[$j]
- Next
- EndIf
- $aArray[$j + 1] = $vTmp
- Next
- Return
- EndIf
- ; QuickSort
- Local $L = $iStart, $R = $iEnd, $vPivot = $aArray[Int(($iStart + $iEnd) / 2)], $bNum = IsNumber($vPivot)
- Do
- If $bNum Then
- ; While $aArray[$L] < $vPivot
- While ($aArray[$L] < $vPivot And IsNumber($aArray[$L])) Or (Not IsNumber($aArray[$L]) And StringCompare($aArray[$L], $vPivot) < 0)
- $L += 1
- WEnd
- ; While $aArray[$R] > $vPivot
- While ($aArray[$R] > $vPivot And IsNumber($aArray[$R])) Or (Not IsNumber($aArray[$R]) And StringCompare($aArray[$R], $vPivot) > 0)
- $R -= 1
- WEnd
- Else
- While (StringCompare($aArray[$L], $vPivot) < 0)
- $L += 1
- WEnd
- While (StringCompare($aArray[$R], $vPivot) > 0)
- $R -= 1
- WEnd
- EndIf
- ; Swap
- If $L <= $R Then
- $vTmp = $aArray[$L]
- $aArray[$L] = $aArray[$R]
- $aArray[$R] = $vTmp
- $L += 1
- $R -= 1
- EndIf
- Until $L > $R
- __ArrayQuickSort1D($aArray, $iStart, $R)
- __ArrayQuickSort1D($aArray, $L, $iEnd)
- EndFunc ;==>__ArrayQuickSort1D
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __ArrayQuickSort2D
- ; Description ...: Helper function for sorting 2D arrays
- ; Syntax.........: __ArrayQuickSort2D ( ByRef $aArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax )
- ; Parameters ....: $aArray - Array to sort
- ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!)
- ; $iStart - Index of array to start sorting at
- ; $iEnd - Index of array to stop sorting at
- ; $iSubItem - Sub-index to sort on in 2D arrays
- ; $iSubMax - Maximum sub-index that array has
- ; Return values .: None
- ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
- ; Modified.......:
- ; Remarks .......: For Internal Use Only
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __ArrayQuickSort2D(ByRef $aArray, Const ByRef $iStep, Const ByRef $iStart, Const ByRef $iEnd, Const ByRef $iSubItem, Const ByRef $iSubMax)
- If $iEnd <= $iStart Then Return
- ; QuickSort
- Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $aArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $bNum = IsNumber($vPivot)
- Do
- If $bNum Then
- ; While $aArray[$L][$iSubItem] < $vPivot
- While ($iStep * ($aArray[$L][$iSubItem] - $vPivot) < 0 And IsNumber($aArray[$L][$iSubItem])) Or (Not IsNumber($aArray[$L][$iSubItem]) And $iStep * StringCompare($aArray[$L][$iSubItem], $vPivot) < 0)
- $L += 1
- WEnd
- ; While $aArray[$R][$iSubItem] > $vPivot
- While ($iStep * ($aArray[$R][$iSubItem] - $vPivot) > 0 And IsNumber($aArray[$R][$iSubItem])) Or (Not IsNumber($aArray[$R][$iSubItem]) And $iStep * StringCompare($aArray[$R][$iSubItem], $vPivot) > 0)
- $R -= 1
- WEnd
- Else
- While ($iStep * StringCompare($aArray[$L][$iSubItem], $vPivot) < 0)
- $L += 1
- WEnd
- While ($iStep * StringCompare($aArray[$R][$iSubItem], $vPivot) > 0)
- $R -= 1
- WEnd
- EndIf
- ; Swap
- If $L <= $R Then
- For $i = 0 To $iSubMax
- $vTmp = $aArray[$L][$i]
- $aArray[$L][$i] = $aArray[$R][$i]
- $aArray[$R][$i] = $vTmp
- Next
- $L += 1
- $R -= 1
- EndIf
- Until $L > $R
- __ArrayQuickSort2D($aArray, $iStep, $iStart, $R, $iSubItem, $iSubMax)
- __ArrayQuickSort2D($aArray, $iStep, $L, $iEnd, $iSubItem, $iSubMax)
- EndFunc ;==>__ArrayQuickSort2D
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __ArrayDualPivotSort
- ; Description ...: Helper function for sorting 1D arrays
- ; Syntax.........: __ArrayDualPivotSort ( ByRef $aArray, $iPivot_Left, $iPivot_Right [, $bLeftMost = True ] )
- ; Parameters ....: $aArray - Array to sort
- ; $iPivot_Left - Index of the array to start sorting at
- ; $iPivot_Right - Index of the array to stop sorting at
- ; $bLeftMost - Indicates if this part is the leftmost in the range
- ; Return values .: None
- ; Author ........: Erik Pilsits
- ; Modified.......: Melba23
- ; Remarks .......: For Internal Use Only
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __ArrayDualPivotSort(ByRef $aArray, $iPivot_Left, $iPivot_Right, $bLeftMost = True)
- If $iPivot_Left > $iPivot_Right Then Return
- Local $iLength = $iPivot_Right - $iPivot_Left + 1
- Local $i, $j, $k, $iAi, $iAk, $iA1, $iA2, $iLast
- If $iLength < 45 Then ; Use insertion sort for small arrays - value chosen empirically
- If $bLeftMost Then
- $i = $iPivot_Left
- While $i < $iPivot_Right
- $j = $i
- $iAi = $aArray[$i + 1]
- While $iAi < $aArray[$j]
- $aArray[$j + 1] = $aArray[$j]
- $j -= 1
- If $j + 1 = $iPivot_Left Then ExitLoop
- WEnd
- $aArray[$j + 1] = $iAi
- $i += 1
- WEnd
- Else
- While 1
- If $iPivot_Left >= $iPivot_Right Then Return 1
- $iPivot_Left += 1
- If $aArray[$iPivot_Left] < $aArray[$iPivot_Left - 1] Then ExitLoop
- WEnd
- While 1
- $k = $iPivot_Left
- $iPivot_Left += 1
- If $iPivot_Left > $iPivot_Right Then ExitLoop
- $iA1 = $aArray[$k]
- $iA2 = $aArray[$iPivot_Left]
- If $iA1 < $iA2 Then
- $iA2 = $iA1
- $iA1 = $aArray[$iPivot_Left]
- EndIf
- $k -= 1
- While $iA1 < $aArray[$k]
- $aArray[$k + 2] = $aArray[$k]
- $k -= 1
- WEnd
- $aArray[$k + 2] = $iA1
- While $iA2 < $aArray[$k]
- $aArray[$k + 1] = $aArray[$k]
- $k -= 1
- WEnd
- $aArray[$k + 1] = $iA2
- $iPivot_Left += 1
- WEnd
- $iLast = $aArray[$iPivot_Right]
- $iPivot_Right -= 1
- While $iLast < $aArray[$iPivot_Right]
- $aArray[$iPivot_Right + 1] = $aArray[$iPivot_Right]
- $iPivot_Right -= 1
- WEnd
- $aArray[$iPivot_Right + 1] = $iLast
- EndIf
- Return 1
- EndIf
- Local $iSeventh = BitShift($iLength, 3) + BitShift($iLength, 6) + 1
- Local $iE1, $iE2, $iE3, $iE4, $iE5, $t
- $iE3 = Ceiling(($iPivot_Left + $iPivot_Right) / 2)
- $iE2 = $iE3 - $iSeventh
- $iE1 = $iE2 - $iSeventh
- $iE4 = $iE3 + $iSeventh
- $iE5 = $iE4 + $iSeventh
- If $aArray[$iE2] < $aArray[$iE1] Then
- $t = $aArray[$iE2]
- $aArray[$iE2] = $aArray[$iE1]
- $aArray[$iE1] = $t
- EndIf
- If $aArray[$iE3] < $aArray[$iE2] Then
- $t = $aArray[$iE3]
- $aArray[$iE3] = $aArray[$iE2]
- $aArray[$iE2] = $t
- If $t < $aArray[$iE1] Then
- $aArray[$iE2] = $aArray[$iE1]
- $aArray[$iE1] = $t
- EndIf
- EndIf
- If $aArray[$iE4] < $aArray[$iE3] Then
- $t = $aArray[$iE4]
- $aArray[$iE4] = $aArray[$iE3]
- $aArray[$iE3] = $t
- If $t < $aArray[$iE2] Then
- $aArray[$iE3] = $aArray[$iE2]
- $aArray[$iE2] = $t
- If $t < $aArray[$iE1] Then
- $aArray[$iE2] = $aArray[$iE1]
- $aArray[$iE1] = $t
- EndIf
- EndIf
- EndIf
- If $aArray[$iE5] < $aArray[$iE4] Then
- $t = $aArray[$iE5]
- $aArray[$iE5] = $aArray[$iE4]
- $aArray[$iE4] = $t
- If $t < $aArray[$iE3] Then
- $aArray[$iE4] = $aArray[$iE3]
- $aArray[$iE3] = $t
- If $t < $aArray[$iE2] Then
- $aArray[$iE3] = $aArray[$iE2]
- $aArray[$iE2] = $t
- If $t < $aArray[$iE1] Then
- $aArray[$iE2] = $aArray[$iE1]
- $aArray[$iE1] = $t
- EndIf
- EndIf
- EndIf
- EndIf
- Local $iLess = $iPivot_Left
- Local $iGreater = $iPivot_Right
- If (($aArray[$iE1] <> $aArray[$iE2]) And ($aArray[$iE2] <> $aArray[$iE3]) And ($aArray[$iE3] <> $aArray[$iE4]) And ($aArray[$iE4] <> $aArray[$iE5])) Then
- Local $iPivot_1 = $aArray[$iE2]
- Local $iPivot_2 = $aArray[$iE4]
- $aArray[$iE2] = $aArray[$iPivot_Left]
- $aArray[$iE4] = $aArray[$iPivot_Right]
- Do
- $iLess += 1
- Until $aArray[$iLess] >= $iPivot_1
- Do
- $iGreater -= 1
- Until $aArray[$iGreater] <= $iPivot_2
- $k = $iLess
- While $k <= $iGreater
- $iAk = $aArray[$k]
- If $iAk < $iPivot_1 Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $iAk
- $iLess += 1
- ElseIf $iAk > $iPivot_2 Then
- While $aArray[$iGreater] > $iPivot_2
- $iGreater -= 1
- If $iGreater + 1 = $k Then ExitLoop 2
- WEnd
- If $aArray[$iGreater] < $iPivot_1 Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $aArray[$iGreater]
- $iLess += 1
- Else
- $aArray[$k] = $aArray[$iGreater]
- EndIf
- $aArray[$iGreater] = $iAk
- $iGreater -= 1
- EndIf
- $k += 1
- WEnd
- $aArray[$iPivot_Left] = $aArray[$iLess - 1]
- $aArray[$iLess - 1] = $iPivot_1
- $aArray[$iPivot_Right] = $aArray[$iGreater + 1]
- $aArray[$iGreater + 1] = $iPivot_2
- __ArrayDualPivotSort($aArray, $iPivot_Left, $iLess - 2, True)
- __ArrayDualPivotSort($aArray, $iGreater + 2, $iPivot_Right, False)
- If ($iLess < $iE1) And ($iE5 < $iGreater) Then
- While $aArray[$iLess] = $iPivot_1
- $iLess += 1
- WEnd
- While $aArray[$iGreater] = $iPivot_2
- $iGreater -= 1
- WEnd
- $k = $iLess
- While $k <= $iGreater
- $iAk = $aArray[$k]
- If $iAk = $iPivot_1 Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $iAk
- $iLess += 1
- ElseIf $iAk = $iPivot_2 Then
- While $aArray[$iGreater] = $iPivot_2
- $iGreater -= 1
- If $iGreater + 1 = $k Then ExitLoop 2
- WEnd
- If $aArray[$iGreater] = $iPivot_1 Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $iPivot_1
- $iLess += 1
- Else
- $aArray[$k] = $aArray[$iGreater]
- EndIf
- $aArray[$iGreater] = $iAk
- $iGreater -= 1
- EndIf
- $k += 1
- WEnd
- EndIf
- __ArrayDualPivotSort($aArray, $iLess, $iGreater, False)
- Else
- Local $iPivot = $aArray[$iE3]
- $k = $iLess
- While $k <= $iGreater
- If $aArray[$k] = $iPivot Then
- $k += 1
- ContinueLoop
- EndIf
- $iAk = $aArray[$k]
- If $iAk < $iPivot Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $iAk
- $iLess += 1
- Else
- While $aArray[$iGreater] > $iPivot
- $iGreater -= 1
- WEnd
- If $aArray[$iGreater] < $iPivot Then
- $aArray[$k] = $aArray[$iLess]
- $aArray[$iLess] = $aArray[$iGreater]
- $iLess += 1
- Else
- $aArray[$k] = $iPivot
- EndIf
- $aArray[$iGreater] = $iAk
- $iGreater -= 1
- EndIf
- $k += 1
- WEnd
- __ArrayDualPivotSort($aArray, $iPivot_Left, $iLess - 1, True)
- __ArrayDualPivotSort($aArray, $iGreater + 1, $iPivot_Right, False)
- EndIf
- EndFunc ;==>__ArrayDualPivotSort
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Melba23
- ; Modified.......:
- ; ===============================================================================================================================
- Func _ArraySwap(ByRef $aArray, $iIndex_1, $iIndex_2, $bCol = False, $iStart = -1, $iEnd = -1)
- If $bCol = Default Then $bCol = False
- If $iStart = Default Then $iStart = -1
- If $iEnd = Default Then $iEnd = -1
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iDim_2 = -1 Then ; 1D array so force defaults
- $bCol = False
- $iStart = -1
- $iEnd = -1
- EndIf
- ; Bounds check
- If $iStart > $iEnd Then Return SetError(5, 0, -1)
- If $bCol Then
- If $iIndex_1 < 0 Or $iIndex_2 > $iDim_2 Then Return SetError(3, 0, -1)
- If $iStart = -1 Then $iStart = 0
- If $iEnd = -1 Then $iEnd = $iDim_1
- Else
- If $iIndex_1 < 0 Or $iIndex_2 > $iDim_1 Then Return SetError(3, 0, -1)
- If $iStart = -1 Then $iStart = 0
- If $iEnd = -1 Then $iEnd = $iDim_2
- EndIf
- Local $vTmp
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- $vTmp = $aArray[$iIndex_1]
- $aArray[$iIndex_1] = $aArray[$iIndex_2]
- $aArray[$iIndex_2] = $vTmp
- Case 2
- If $iStart < -1 Or $iEnd < -1 Then Return SetError(4, 0, -1)
- If $bCol Then
- If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(4, 0, -1)
- For $j = $iStart To $iEnd
- $vTmp = $aArray[$j][$iIndex_1]
- $aArray[$j][$iIndex_1] = $aArray[$j][$iIndex_2]
- $aArray[$j][$iIndex_2] = $vTmp
- Next
- Else
- If $iStart > $iDim_2 Or $iEnd > $iDim_2 Then Return SetError(4, 0, -1)
- For $j = $iStart To $iEnd
- $vTmp = $aArray[$iIndex_1][$j]
- $aArray[$iIndex_1][$j] = $aArray[$iIndex_2][$j]
- $aArray[$iIndex_2][$j] = $vTmp
- Next
- EndIf
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return 1
- EndFunc ;==>_ArraySwap
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Cephas <cephas at clergy dot net>
- ; Modified.......: Jos - added $iStart parameter and logic, Ultima - added $iEnd parameter, make use of _ArrayToString() instead of duplicating efforts; Melba23 - added 2D support
- ; ===============================================================================================================================
- Func _ArrayToClip(Const ByRef $aArray, $sDelim_Col = "|", $iStart_Row = -1, $iEnd_Row = -1, $sDelim_Row = @CRLF, $iStart_Col = -1, $iEnd_Col = -1)
- Local $sResult = _ArrayToString($aArray, $sDelim_Col, $iStart_Row, $iEnd_Row, $sDelim_Row, $iStart_Col, $iEnd_Col)
- If @error Then Return SetError(@error, 0, 0)
- If ClipPut($sResult) Then Return 1
- Return SetError(-1, 0, 0)
- EndFunc ;==>_ArrayToClip
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Brian Keene <brian_keene at yahoo dot com>, Valik - rewritten
- ; Modified.......: Ultima - code cleanup; Melba23 - added support for empty and 2D arrays
- ; ===============================================================================================================================
- Func _ArrayToString(Const ByRef $aArray, $sDelim_Col = "|", $iStart_Row = -1, $iEnd_Row = -1, $sDelim_Row = @CRLF, $iStart_Col = -1, $iEnd_Col = -1)
- If $sDelim_Col = Default Then $sDelim_Col = "|"
- If $sDelim_Row = Default Then $sDelim_Row = @CRLF
- If $iStart_Row = Default Then $iStart_Row = -1
- If $iEnd_Row = Default Then $iEnd_Row = -1
- If $iStart_Col = Default Then $iStart_Col = -1
- If $iEnd_Col = Default Then $iEnd_Col = -1
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- If $iStart_Row = -1 Then $iStart_Row = 0
- If $iEnd_Row = -1 Then $iEnd_Row = $iDim_1
- If $iStart_Row < -1 Or $iEnd_Row < -1 Then Return SetError(3, 0, -1)
- If $iStart_Row > $iDim_1 Or $iEnd_Row > $iDim_1 Then Return SetError(3, 0, "")
- If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
- Local $sRet = ""
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- For $i = $iStart_Row To $iEnd_Row
- $sRet &= $aArray[$i] & $sDelim_Col
- Next
- Return StringTrimRight($sRet, StringLen($sDelim_Col))
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iStart_Col = -1 Then $iStart_Col = 0
- If $iEnd_Col = -1 Then $iEnd_Col = $iDim_2
- If $iStart_Col < -1 Or $iEnd_Col < -1 Then Return SetError(5, 0, -1)
- If $iStart_Col > $iDim_2 Or $iEnd_Col > $iDim_2 Then Return SetError(5, 0, -1)
- If $iStart_Col > $iEnd_Col Then Return SetError(6, 0, -1)
- For $i = $iStart_Row To $iEnd_Row
- For $j = $iStart_Col To $iEnd_Col
- $sRet &= $aArray[$i][$j] & $sDelim_Col
- Next
- $sRet = StringTrimRight($sRet, StringLen($sDelim_Col)) & $sDelim_Row
- Next
- Return StringTrimRight($sRet, StringLen($sDelim_Row))
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return 1
- EndFunc ;==>_ArrayToString
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: jchd
- ; Modified.......: jpm, czardas
- ; ===============================================================================================================================
- Func _ArrayTranspose(ByRef $aArray)
- Switch UBound($aArray, 0)
- Case 0
- Return SetError(2, 0, 0)
- Case 1
- Local $aTemp[1][UBound($aArray)]
- For $i = 0 To UBound($aArray) - 1
- $aTemp[0][$i] = $aArray[$i]
- Next
- $aArray = $aTemp
- Case 2
- Local $iDim_1 = UBound($aArray, 1), $iDim_2 = UBound($aArray, 2)
- If $iDim_1 <> $iDim_2 Then
- Local $aTemp[$iDim_2][$iDim_1]
- For $i = 0 To $iDim_1 - 1
- For $j = 0 To $iDim_2 - 1
- $aTemp[$j][$i] = $aArray[$i][$j]
- Next
- Next
- $aArray = $aTemp
- Else ; optimimal method for a square grid
- Local $vElement
- For $i = 0 To $iDim_1 - 1
- For $j = $i + 1 To $iDim_2 - 1
- $vElement = $aArray[$i][$j]
- $aArray[$i][$j] = $aArray[$j][$i]
- $aArray[$j][$i] = $vElement
- Next
- Next
- EndIf
- Case Else
- Return SetError(1, 0, 0)
- EndSwitch
- Return 1
- EndFunc ;==>_ArrayTranspose
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: Adam Moore (redndahead)
- ; Modified.......: Ultima - code cleanup, optimization; Melba23 - added 2D support
- ; ===============================================================================================================================
- Func _ArrayTrim(ByRef $aArray, $iTrimNum, $iDirection = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0)
- If $iDirection = Default Then $iDirection = 0
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iSubItem = Default Then $iSubItem = 0
- If Not IsArray($aArray) Then Return SetError(1, 0, 0)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- If $iEnd = 0 Then $iEnd = $iDim_1
- If $iStart > $iEnd Then Return SetError(3, 0, -1)
- If $iStart < 0 Or $iEnd < 0 Then Return SetError(3, 0, -1)
- If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(3, 0, -1)
- If $iStart > $iEnd Then Return SetError(4, 0, -1)
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $iDirection Then
- For $i = $iStart To $iEnd
- $aArray[$i] = StringTrimRight($aArray[$i], $iTrimNum)
- Next
- Else
- For $i = $iStart To $iEnd
- $aArray[$i] = StringTrimLeft($aArray[$i], $iTrimNum)
- Next
- EndIf
- Case 2
- Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
- If $iSubItem < 0 Or $iSubItem > $iDim_2 Then Return SetError(5, 0, -1)
- If $iDirection Then
- For $i = $iStart To $iEnd
- $aArray[$i][$iSubItem] = StringTrimRight($aArray[$i][$iSubItem], $iTrimNum)
- Next
- Else
- For $i = $iStart To $iEnd
- $aArray[$i][$iSubItem] = StringTrimLeft($aArray[$i][$iSubItem], $iTrimNum)
- Next
- EndIf
- Case Else
- Return SetError(2, 0, 0)
- EndSwitch
- Return 1
- EndFunc ;==>_ArrayTrim
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: SmOke_N
- ; Modified.......: litlmike, Erik Pilsits, BrewManNH, Melba23
- ; ===============================================================================================================================
- Func _ArrayUnique(Const ByRef $aArray, $iColumn = 0, $iBase = 0, $iCase = 0, $iCount = $ARRAYUNIQUE_COUNT, $iIntType = $ARRAYUNIQUE_AUTO)
- If $iColumn = Default Then $iColumn = 0
- If $iBase = Default Then $iBase = 0
- If $iCase = Default Then $iCase = 0
- If $iCount = Default Then $iCount = $ARRAYUNIQUE_COUNT
- ; Check array
- If UBound($aArray, $UBOUND_ROWS) = 0 Then Return SetError(1, 0, 0)
- Local $iDims = UBound($aArray, $UBOUND_DIMENSIONS), $iNumColumns = UBound($aArray, $UBOUND_COLUMNS)
- If $iDims > 2 Then Return SetError(2, 0, 0)
- ; Check parameters
- If $iBase < 0 Or $iBase > 1 Or (Not IsInt($iBase)) Then Return SetError(3, 0, 0)
- If $iCase < 0 Or $iCase > 1 Or (Not IsInt($iCase)) Then Return SetError(3, 0, 0)
- If $iCount < 0 Or $iCount > 1 Or (Not IsInt($iCount)) Then Return SetError(4, 0, 0)
- If $iIntType < 0 Or $iIntType > 4 Or (Not IsInt($iIntType)) Then Return SetError(5, 0, 0)
- If $iColumn < 0 Or ($iNumColumns = 0 And $iColumn > 0) Or ($iNumColumns > 0 And $iColumn >= $iNumColumns) Then Return SetError(6, 0, 0)
- ; Autocheck of first element
- If $iIntType = $ARRAYUNIQUE_AUTO Then
- Local $bInt, $sVarType
- If $iDims = 1 Then
- $bInt = IsInt($aArray[$iBase])
- $sVarType = VarGetType($aArray[$iBase])
- Else
- $bInt = IsInt($aArray[$iBase][$iColumn])
- $sVarType = VarGetType($aArray[$iBase][$iColumn])
- EndIf
- If $bInt And $sVarType = "Int64" Then
- $iIntType = $ARRAYUNIQUE_FORCE64
- Else
- $iIntType = $ARRAYUNIQUE_FORCE32
- EndIf
- EndIf
- ; Create error handler
- ObjEvent("AutoIt.Error", __ArrayUnique_AutoErrFunc)
- ; Create dictionary
- Local $oDictionary = ObjCreate("Scripting.Dictionary")
- ; Set case sensitivity
- $oDictionary.CompareMode = Number(Not $iCase)
- ; Add elements to dictionary
- Local $vElem, $sType, $vKey, $bCOMError = False
- For $i = $iBase To UBound($aArray) - 1
- If $iDims = 1 Then
- ; 1D array
- $vElem = $aArray[$i]
- Else
- ; 2D array
- $vElem = $aArray[$i][$iColumn]
- EndIf
- ; Determine method to use
- Switch $iIntType
- Case $ARRAYUNIQUE_FORCE32
- ; Use element as key
- $oDictionary.Item($vElem) ; Check if key exists - automatically created if not
- If @error Then
- $bCOMError = True ; Failed with an Int64, Ptr or Binary datatype
- ExitLoop
- EndIf
- Case $ARRAYUNIQUE_FORCE64
- $sType = VarGetType($vElem)
- If $sType = "Int32" Then
- $bCOMError = True ; Failed with an Int32 datatype
- ExitLoop
- EndIf ; Create key
- $vKey = "#" & $sType & "#" & String($vElem)
- If Not $oDictionary.Item($vKey) Then ; Check if key exists
- $oDictionary($vKey) = $vElem ; Store actual value in dictionary
- EndIf
- Case $ARRAYUNIQUE_MATCH
- $sType = VarGetType($vElem)
- If StringLeft($sType, 3) = "Int" Then
- $vKey = "#Int#" & String($vElem)
- Else
- $vKey = "#" & $sType & "#" & String($vElem)
- EndIf
- If Not $oDictionary.Item($vKey) Then ; Check if key exists
- $oDictionary($vKey) = $vElem ; Store actual value in dictionary
- EndIf
- Case $ARRAYUNIQUE_DISTINCT
- $vKey = "#" & VarGetType($vElem) & "#" & String($vElem)
- If Not $oDictionary.Item($vKey) Then ; Check if key exists
- $oDictionary($vKey) = $vElem ; Store actual value in dictionary
- EndIf
- EndSwitch
- Next
- ; Create return array
- Local $aValues, $j = 0
- If $bCOMError Then ; Mismatch Int32/64
- Return SetError(7, 0, 0)
- ElseIf $iIntType <> $ARRAYUNIQUE_FORCE32 Then
- ; Extract values associated with the unique keys
- Local $aValues[$oDictionary.Count]
- For $vKey In $oDictionary.Keys()
- $aValues[$j] = $oDictionary($vKey)
- ; Check for Ptr datatype
- If StringLeft($vKey, 5) = "#Ptr#" Then
- $aValues[$j] = Ptr($aValues[$j])
- EndIf
- $j += 1
- Next
- Else
- ; Only need to list the unique keys
- $aValues = $oDictionary.Keys()
- EndIf
- ; Add count if required
- If $iCount Then
- _ArrayInsert($aValues, 0, $oDictionary.Count)
- EndIf
- ; Return array
- Return $aValues
- EndFunc ;==>_ArrayUnique
- ; #FUNCTION# ====================================================================================================================
- ; Author ........: jchd, jpm
- ; Modified.......:
- ; ===============================================================================================================================
- Func _Array1DToHistogram($aArray, $iSizing = 100)
- If UBound($aArray, 0) > 1 Then Return SetError(1, 0, "")
- $iSizing = $iSizing * 8
- Local $t, $n, $iMin = 0, $iMax = 0, $iOffset = 0
- For $i = 0 To UBound($aArray) - 1
- $t = $aArray[$i]
- $t = IsNumber($t) ? Round($t) : 0
- If $t < $iMin Then $iMin = $t
- If $t > $iMax Then $iMax = $t
- Next
- Local $iRange = Int(Round(($iMax - $iMin) / 8)) * 8
- Local $iSpaceRatio = 4
- For $i = 0 To UBound($aArray) - 1
- $t = $aArray[$i]
- If $t Then
- $n = Abs(Round(($iSizing * $t) / $iRange) / 8)
- $aArray[$i] = ""
- If $t > 0 Then
- If $iMin Then
- $iOffset = Int(Abs(Round(($iSizing * $iMin) / $iRange) / 8) / 8 * $iSpaceRatio)
- $aArray[$i] = __Array_StringRepeat(ChrW(0x20), $iOffset)
- EndIf
- Else
- If $iMin <> $t Then
- $iOffset = Int(Abs(Round(($iSizing * ($t - $iMin)) / $iRange) / 8) / 8 * $iSpaceRatio)
- $aArray[$i] = __Array_StringRepeat(ChrW(0x20), $iOffset)
- EndIf
- EndIf
- $aArray[$i] &= __Array_StringRepeat(ChrW(0x2588), Int($n / 8))
- $n = Mod($n, 8)
- If $n > 0 Then $aArray[$i] &= ChrW(0x2588 + 8 - $n)
- $aArray[$i] &= ' ' & $t
- Else
- $aArray[$i] = ""
- EndIf
- Next
- Return $aArray
- EndFunc ;==>_Array1DToHistogram
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __Array_StringRepeat
- ; Description ...: Repeats a string a specified number of times
- ; Syntax.........: __Array_StringRepeat ( $sString, $iRepeatCount )
- ; Parameters ....: $sString - String to repeat
- ; $iRepeatCount - Number of times to repeat the string
- ; Return values .: a string with specified number of repeats.
- ; Author ........: Jeremy Landes <jlandes at landeserve dot com>
- ; Modified.......: jpm
- ; Remarks .......: This function is used internally. similar to _StringRepeat() but if $iRepeatCount = 0 returns ""
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __Array_StringRepeat($sString, $iRepeatCount)
- ; Casting Int() takes care of String/Int, Numbers.
- $iRepeatCount = Int($iRepeatCount)
- ; Zero is a valid repeat integer.
- If StringLen($sString) < 1 Or $iRepeatCount <= 0 Then Return SetError(1, 0, "")
- Local $sResult = ""
- While $iRepeatCount > 1
- If BitAND($iRepeatCount, 1) Then $sResult &= $sString
- $sString &= $sString
- $iRepeatCount = BitShift($iRepeatCount, 1)
- WEnd
- Return $sString & $sResult
- EndFunc ;==>__Array_StringRepeat
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __Array_ExeterInternal
- ; Description ...: Permute Function based on an algorithm from Exeter University.
- ; Syntax.........: __Array_ExeterInternal ( ByRef $aArray, $iStart, $iSize, $sDelimiter, ByRef $aIdx, ByRef $aResult )
- ; Parameters ....: $aArray - The Array to get Permutations
- ; $iStart - Starting Point for Loop
- ; $iSize - End Point for Loop
- ; $sDelimiter - String result separator
- ; $aIdx - Array Used in Rotations
- ; $aResult - Resulting Array
- ; Return values .: Success - Computer name
- ; Author ........: Erik Pilsits
- ; Modified.......: 07/08/2008
- ; Remarks .......: This function is used internally. Permute Function based on an algorithm from Exeter University.
- ; +
- ; http://www.bearcave.com/random_hacks/permute.html
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __Array_ExeterInternal(ByRef $aArray, $iStart, $iSize, $sDelimiter, ByRef $aIdx, ByRef $aResult, ByRef $iCount)
- If $iStart == $iSize - 1 Then
- For $i = 0 To $iSize - 1
- $aResult[$iCount] &= $aArray[$aIdx[$i]] & $sDelimiter
- Next
- If $sDelimiter <> "" Then $aResult[$iCount] = StringTrimRight($aResult[$iCount], StringLen($sDelimiter))
- $iCount += 1
- Else
- Local $iTemp
- For $i = $iStart To $iSize - 1
- $iTemp = $aIdx[$i]
- $aIdx[$i] = $aIdx[$iStart]
- $aIdx[$iStart] = $iTemp
- __Array_ExeterInternal($aArray, $iStart + 1, $iSize, $sDelimiter, $aIdx, $aResult, $iCount)
- $aIdx[$iStart] = $aIdx[$i]
- $aIdx[$i] = $iTemp
- Next
- EndIf
- EndFunc ;==>__Array_ExeterInternal
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __Array_Combinations
- ; Description ...: Creates Combination
- ; Syntax.........: __Array_Combinations ( $iN, $iR )
- ; Parameters ....: $iN - Value passed on from UBound($aArray)
- ; $iR - Size of the combinations set
- ; Return values .: Integer value of the number of combinations
- ; Author ........: Erik Pilsits
- ; Modified.......: 07/08/2008
- ; Remarks .......: This function is used internally. PBased on an algorithm by Kenneth H. Rosen.
- ; +
- ; http://www.bearcave.com/random_hacks/permute.html
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __Array_Combinations($iN, $iR)
- Local $i_Total = 1
- For $i = $iR To 1 Step -1
- $i_Total *= ($iN / $i)
- $iN -= 1
- Next
- Return Round($i_Total)
- EndFunc ;==>__Array_Combinations
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; Name...........: __Array_GetNext
- ; Description ...: Creates Combination
- ; Syntax.........: __Array_GetNext ( $iN, $iR, ByRef $iLeft, $iTotal, ByRef $aIdx )
- ; Parameters ....: $iN - Value passed on from UBound($aArray)
- ; $iR - Size of the combinations set
- ; $iLeft - Remaining number of combinations
- ; $iTotal - Total number of combinations
- ; $aIdx - Array containing combinations
- ; Return values .: Function only changes values ByRef
- ; Author ........: Erik Pilsits
- ; Modified.......: 07/08/2008
- ; Remarks .......: This function is used internally. PBased on an algorithm by Kenneth H. Rosen.
- ; +
- ; http://www.bearcave.com/random_hacks/permute.html
- ; Related .......:
- ; Link ..........:
- ; Example .......:
- ; ===============================================================================================================================
- Func __Array_GetNext($iN, $iR, ByRef $iLeft, $iTotal, ByRef $aIdx)
- If $iLeft == $iTotal Then
- $iLeft -= 1
- Return
- EndIf
- Local $i = $iR - 1
- While $aIdx[$i] == $iN - $iR + $i
- $i -= 1
- WEnd
- $aIdx[$i] += 1
- For $j = $i + 1 To $iR - 1
- $aIdx[$j] = $aIdx[$i] + $j - $i
- Next
- $iLeft -= 1
- EndFunc ;==>__Array_GetNext
- Func __Array_MinMaxIndex(Const ByRef $aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem, $fuComparison) ; Always swapped the comparison params around e.g. it was for min 100 > 1000 whereas 1000 < 100 makes more sense in a min function.
- If $iCompNumeric = Default Then $iCompNumeric = 0
- If $iCompNumeric <> 1 Then $iCompNumeric = 0
- If $iStart = Default Then $iStart = 0
- If $iEnd = Default Then $iEnd = 0
- If $iSubItem = Default Then $iSubItem = 0
- If Not IsArray($aArray) Then Return SetError(1, 0, -1)
- Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
- If $iDim_1 < 0 Then Return SetError(1, 0, -1)
- If $iEnd = -1 Then $iEnd = $iDim_1
- If $iStart = -1 Then $iStart = 0
- If $iStart < -1 Or $iEnd < -1 Then Return SetError(3, 0, -1)
- If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(3, 0, -1)
- If $iStart > $iEnd Then Return SetError(4, 0, -1)
- If $iDim_1 < 0 Then Return SetError(5, 0, -1)
- Local $iMaxMinIndex = $iStart
- Switch UBound($aArray, $UBOUND_DIMENSIONS)
- Case 1
- If $iCompNumeric Then
- For $i = $iStart To $iEnd
- If $fuComparison(Number($aArray[$i]), Number($aArray[$iMaxMinIndex])) Then $iMaxMinIndex = $i
- Next
- Else
- For $i = $iStart To $iEnd
- If $fuComparison($aArray[$i], $aArray[$iMaxMinIndex]) Then $iMaxMinIndex = $i
- Next
- EndIf
- Case 2
- If $iSubItem < 0 Or $iSubItem > UBound($aArray, $UBOUND_COLUMNS) - 1 Then Return SetError(6, 0, -1)
- If $iCompNumeric Then
- For $i = $iStart To $iEnd
- If $fuComparison(Number($aArray[$i][$iSubItem]), Number($aArray[$iMaxMinIndex][$iSubItem])) Then $iMaxMinIndex = $i
- Next
- Else
- For $i = $iStart To $iEnd
- If $fuComparison($aArray[$i][$iSubItem], $aArray[$iMaxMinIndex][$iSubItem]) Then $iMaxMinIndex = $i
- Next
- EndIf
- Case Else
- Return SetError(2, 0, -1)
- EndSwitch
- Return $iMaxMinIndex
- EndFunc ;==>__Array_MinMaxIndex
- Func __Array_GreaterThan($vValue1, $vValue2)
- Return $vValue1 > $vValue2
- EndFunc ;==>__Array_GreaterThan
- Func __Array_LessThan($vValue1, $vValue2)
- Return $vValue1 < $vValue2
- EndFunc ;==>__Array_LessThan
- Func __ArrayUnique_AutoErrFunc()
- ; Do nothing special, just check @error after suspect functions.
- EndFunc ;==>__ArrayUnique_AutoErrFunc
|