Array.au3 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124
  1. #include-Once
  2. #include "ArrayDisplayInternals.au3"
  3. #include "AutoItConstants.au3"
  4. #include "MsgBoxConstants.au3"
  5. #include "StringConstants.au3"
  6. ; #INDEX# =======================================================================================================================
  7. ; Title .........: Array
  8. ; AutoIt Version : 3.3.14.5
  9. ; Language ......: English
  10. ; Description ...: Functions for manipulating arrays.
  11. ; Author(s) .....: JdeB, Erik Pilsits, Ultima, Dale (Klaatu) Thompson, Cephas,randallc, Gary Frost, GEOSoft,
  12. ; Helias Gerassimou(hgeras), Brian Keene, Michael Michta, gcriaco, LazyCoder, Tylo, David Nuttall,
  13. ; Adam Moore (redndahead), SmOke_N, litlmike, Valik, Melba23
  14. ; ===============================================================================================================================
  15. ; #CURRENT# =====================================================================================================================
  16. ; _ArrayAdd
  17. ; _ArrayBinarySearch
  18. ; _ArrayColDelete
  19. ; _ArrayColInsert
  20. ; _ArrayCombinations
  21. ; _ArrayConcatenate
  22. ; _ArrayDelete
  23. ; _ArrayDisplay
  24. ; _ArrayExtract
  25. ; _ArrayFindAll
  26. ; _ArrayInsert
  27. ; _ArrayMax
  28. ; _ArrayMaxIndex
  29. ; _ArrayMin
  30. ; _ArrayMinIndex
  31. ; _ArrayPermute
  32. ; _ArrayPop
  33. ; _ArrayPush
  34. ; _ArrayReverse
  35. ; _ArraySearch
  36. ; _ArrayShuffle
  37. ; _ArraySort
  38. ; _ArraySwap
  39. ; _ArrayToClip
  40. ; _ArrayToString
  41. ; _ArrayTranspose
  42. ; _ArrayTrim
  43. ; _ArrayUnique
  44. ; _Array1DToHistogram
  45. ; ===============================================================================================================================
  46. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  47. ; __Array_Combinations
  48. ; __Array_ExeterInternal
  49. ; __Array_GetNext
  50. ; __Array_GreaterThan
  51. ; __Array_LessThan
  52. ; __Array_MinMaxIndex
  53. ; __Array_StringRepeat
  54. ; __ArrayDualPivotSort
  55. ; __ArrayQuickSort1D
  56. ; __ArrayQuickSort2D
  57. ; __ArrayUnique_AutoErrFunc
  58. ; ===============================================================================================================================
  59. ; #GLOBAL CONSTANTS# ============================================================================================================
  60. Global Enum $ARRAYFILL_FORCE_DEFAULT, $ARRAYFILL_FORCE_SINGLEITEM, $ARRAYFILL_FORCE_INT, $ARRAYFILL_FORCE_NUMBER, _
  61. $ARRAYFILL_FORCE_PTR, $ARRAYFILL_FORCE_HWND, $ARRAYFILL_FORCE_STRING, $ARRAYFILL_FORCE_BOOLEAN
  62. Global Enum $ARRAYUNIQUE_NOCOUNT, $ARRAYUNIQUE_COUNT
  63. Global Enum $ARRAYUNIQUE_AUTO, $ARRAYUNIQUE_FORCE32, $ARRAYUNIQUE_FORCE64, $ARRAYUNIQUE_MATCH, $ARRAYUNIQUE_DISTINCT
  64. ; ===============================================================================================================================
  65. ; #FUNCTION# ====================================================================================================================
  66. ; Author ........: Jos
  67. ; Modified.......: Ultima - code cleanup; Melba23 - added 2D support & multiple addition
  68. ; ===============================================================================================================================
  69. Func _ArrayAdd(ByRef $aArray, $vValue, $iStart = 0, $sDelim_Item = "|", $sDelim_Row = @CRLF, $iForce = $ARRAYFILL_FORCE_DEFAULT)
  70. If $iStart = Default Then $iStart = 0
  71. If $sDelim_Item = Default Then $sDelim_Item = "|"
  72. If $sDelim_Row = Default Then $sDelim_Row = @CRLF
  73. If $iForce = Default Then $iForce = $ARRAYFILL_FORCE_DEFAULT
  74. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  75. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
  76. Local $hDataType = 0
  77. Switch $iForce
  78. Case $ARRAYFILL_FORCE_INT
  79. $hDataType = Int
  80. Case $ARRAYFILL_FORCE_NUMBER
  81. $hDataType = Number
  82. Case $ARRAYFILL_FORCE_PTR
  83. $hDataType = Ptr
  84. Case $ARRAYFILL_FORCE_HWND
  85. $hDataType = Hwnd
  86. Case $ARRAYFILL_FORCE_STRING
  87. $hDataType = String
  88. Case $ARRAYFILL_FORCE_BOOLEAN
  89. $hDataType = "Boolean"
  90. EndSwitch
  91. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  92. Case 1
  93. If $iForce = $ARRAYFILL_FORCE_SINGLEITEM Then
  94. ReDim $aArray[$iDim_1 + 1]
  95. $aArray[$iDim_1] = $vValue
  96. Return $iDim_1
  97. EndIf
  98. If IsArray($vValue) Then
  99. If UBound($vValue, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(5, 0, -1)
  100. $hDataType = 0
  101. Else
  102. Local $aTmp = StringSplit($vValue, $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  103. If UBound($aTmp, $UBOUND_ROWS) = 1 Then
  104. $aTmp[0] = $vValue
  105. EndIf
  106. $vValue = $aTmp
  107. EndIf
  108. Local $iAdd = UBound($vValue, $UBOUND_ROWS)
  109. ReDim $aArray[$iDim_1 + $iAdd]
  110. For $i = 0 To $iAdd - 1
  111. If String($hDataType) = "Boolean" Then
  112. Switch $vValue[$i]
  113. Case "True", "1"
  114. $aArray[$iDim_1 + $i] = True
  115. Case "False", "0", ""
  116. $aArray[$iDim_1 + $i] = False
  117. EndSwitch
  118. ElseIf IsFunc($hDataType) Then
  119. $aArray[$iDim_1 + $i] = $hDataType($vValue[$i])
  120. Else
  121. $aArray[$iDim_1 + $i] = $vValue[$i]
  122. EndIf
  123. Next
  124. Return $iDim_1 + $iAdd - 1
  125. Case 2
  126. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
  127. If $iStart < 0 Or $iStart > $iDim_2 - 1 Then Return SetError(4, 0, -1)
  128. Local $iValDim_1, $iValDim_2 = 0, $iColCount
  129. If IsArray($vValue) Then
  130. If UBound($vValue, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(5, 0, -1)
  131. $iValDim_1 = UBound($vValue, $UBOUND_ROWS)
  132. $iValDim_2 = UBound($vValue, $UBOUND_COLUMNS)
  133. $hDataType = 0
  134. Else
  135. ; Convert string to 2D array
  136. Local $aSplit_1 = StringSplit($vValue, $sDelim_Row, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  137. $iValDim_1 = UBound($aSplit_1, $UBOUND_ROWS)
  138. Local $aTmp[$iValDim_1][0], $aSplit_2
  139. For $i = 0 To $iValDim_1 - 1
  140. $aSplit_2 = StringSplit($aSplit_1[$i], $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  141. $iColCount = UBound($aSplit_2)
  142. If $iColCount > $iValDim_2 Then
  143. ; Increase array size to fit max number of items on line
  144. $iValDim_2 = $iColCount
  145. ReDim $aTmp[$iValDim_1][$iValDim_2]
  146. EndIf
  147. For $j = 0 To $iColCount - 1
  148. $aTmp[$i][$j] = $aSplit_2[$j]
  149. Next
  150. Next
  151. $vValue = $aTmp
  152. EndIf
  153. ; Check if too many columns to fit
  154. If UBound($vValue, $UBOUND_COLUMNS) + $iStart > UBound($aArray, $UBOUND_COLUMNS) Then Return SetError(3, 0, -1)
  155. ReDim $aArray[$iDim_1 + $iValDim_1][$iDim_2]
  156. For $iWriteTo_Index = 0 To $iValDim_1 - 1
  157. For $j = 0 To $iDim_2 - 1
  158. If $j < $iStart Then
  159. $aArray[$iWriteTo_Index + $iDim_1][$j] = ""
  160. ElseIf $j - $iStart > $iValDim_2 - 1 Then
  161. $aArray[$iWriteTo_Index + $iDim_1][$j] = ""
  162. Else
  163. If String($hDataType) = "Boolean" Then
  164. Switch $vValue[$iWriteTo_Index][$j - $iStart]
  165. Case "True", "1"
  166. $aArray[$iWriteTo_Index + $iDim_1][$j] = True
  167. Case "False", "0", ""
  168. $aArray[$iWriteTo_Index + $iDim_1][$j] = False
  169. EndSwitch
  170. ElseIf IsFunc($hDataType) Then
  171. $aArray[$iWriteTo_Index + $iDim_1][$j] = $hDataType($vValue[$iWriteTo_Index][$j - $iStart])
  172. Else
  173. $aArray[$iWriteTo_Index + $iDim_1][$j] = $vValue[$iWriteTo_Index][$j - $iStart]
  174. EndIf
  175. EndIf
  176. Next
  177. Next
  178. Case Else
  179. Return SetError(2, 0, -1)
  180. EndSwitch
  181. Return UBound($aArray, $UBOUND_ROWS) - 1
  182. EndFunc ;==>_ArrayAdd
  183. ; #FUNCTION# ====================================================================================================================
  184. ; Author ........: Jos
  185. ; Modified.......: Ultima - added $iEnd as parameter, code cleanup; Melba23 - added support for empty & 2D arrays
  186. ; ===============================================================================================================================
  187. Func _ArrayBinarySearch(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iColumn = 0)
  188. If $iStart = Default Then $iStart = 0
  189. If $iEnd = Default Then $iEnd = 0
  190. If $iColumn = Default Then $iColumn = 0
  191. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  192. ; Bounds checking
  193. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
  194. If $iDim_1 = 0 Then Return SetError(6, 0, -1)
  195. If $iEnd < 1 Or $iEnd > $iDim_1 - 1 Then $iEnd = $iDim_1 - 1
  196. If $iStart < 0 Then $iStart = 0
  197. If $iStart > $iEnd Then Return SetError(4, 0, -1)
  198. Local $iMid = Int(($iEnd + $iStart) / 2)
  199. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  200. Case 1
  201. If $aArray[$iStart] > $vValue Or $aArray[$iEnd] < $vValue Then Return SetError(2, 0, -1)
  202. ; Search
  203. While $iStart <= $iMid And $vValue <> $aArray[$iMid]
  204. If $vValue < $aArray[$iMid] Then
  205. $iEnd = $iMid - 1
  206. Else
  207. $iStart = $iMid + 1
  208. EndIf
  209. $iMid = Int(($iEnd + $iStart) / 2)
  210. WEnd
  211. If $iStart > $iEnd Then Return SetError(3, 0, -1) ; Entry not found
  212. Case 2
  213. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  214. If $iColumn < 0 Or $iColumn > $iDim_2 Then Return SetError(7, 0, -1)
  215. If $aArray[$iStart][$iColumn] > $vValue Or $aArray[$iEnd][$iColumn] < $vValue Then Return SetError(2, 0, -1)
  216. ; Search
  217. While $iStart <= $iMid And $vValue <> $aArray[$iMid][$iColumn]
  218. If $vValue < $aArray[$iMid][$iColumn] Then
  219. $iEnd = $iMid - 1
  220. Else
  221. $iStart = $iMid + 1
  222. EndIf
  223. $iMid = Int(($iEnd + $iStart) / 2)
  224. WEnd
  225. If $iStart > $iEnd Then Return SetError(3, 0, -1) ; Entry not found
  226. Case Else
  227. Return SetError(5, 0, -1)
  228. EndSwitch
  229. Return $iMid
  230. EndFunc ;==>_ArrayBinarySearch
  231. ; #FUNCTION# ====================================================================================================================
  232. ; Author ........: Melba23
  233. ; Modified.......:
  234. ; ===============================================================================================================================
  235. Func _ArrayColDelete(ByRef $aArray, $iColumn, $bConvert = False)
  236. If $bConvert = Default Then $bConvert = False
  237. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  238. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
  239. If UBound($aArray, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(2, 0, -1)
  240. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
  241. Switch $iDim_2
  242. Case 2
  243. If $iColumn < 0 Or $iColumn > 1 Then Return SetError(3, 0, -1)
  244. If $bConvert Then
  245. Local $aTempArray[$iDim_1]
  246. For $i = 0 To $iDim_1 - 1
  247. $aTempArray[$i] = $aArray[$i][(Not $iColumn)]
  248. Next
  249. $aArray = $aTempArray
  250. Else
  251. ContinueCase
  252. EndIf
  253. Case Else
  254. If $iColumn < 0 Or $iColumn > $iDim_2 - 1 Then Return SetError(3, 0, -1)
  255. For $i = 0 To $iDim_1 - 1
  256. For $j = $iColumn To $iDim_2 - 2
  257. $aArray[$i][$j] = $aArray[$i][$j + 1]
  258. Next
  259. Next
  260. ReDim $aArray[$iDim_1][$iDim_2 - 1]
  261. EndSwitch
  262. Return UBound($aArray, $UBOUND_COLUMNS)
  263. EndFunc ;==>_ArrayColDelete
  264. ; #FUNCTION# ====================================================================================================================
  265. ; Author ........: Melba23
  266. ; Modified.......:
  267. ; ===============================================================================================================================
  268. Func _ArrayColInsert(ByRef $aArray, $iColumn)
  269. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  270. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
  271. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  272. Case 1
  273. Local $aTempArray[$iDim_1][2]
  274. Switch $iColumn
  275. Case 0, 1
  276. For $i = 0 To $iDim_1 - 1
  277. $aTempArray[$i][(Not $iColumn)] = $aArray[$i]
  278. Next
  279. Case Else
  280. Return SetError(3, 0, -1)
  281. EndSwitch
  282. $aArray = $aTempArray
  283. Case 2
  284. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
  285. If $iColumn < 0 Or $iColumn > $iDim_2 Then Return SetError(3, 0, -1)
  286. ReDim $aArray[$iDim_1][$iDim_2 + 1]
  287. For $i = 0 To $iDim_1 - 1
  288. For $j = $iDim_2 To $iColumn + 1 Step -1
  289. $aArray[$i][$j] = $aArray[$i][$j - 1]
  290. Next
  291. $aArray[$i][$iColumn] = ""
  292. Next
  293. Case Else
  294. Return SetError(2, 0, -1)
  295. EndSwitch
  296. Return UBound($aArray, $UBOUND_COLUMNS)
  297. EndFunc ;==>_ArrayColInsert
  298. ; #FUNCTION# ====================================================================================================================
  299. ; Author ........: Erik Pilsits
  300. ; Modified.......: 07/08/2008
  301. ; ===============================================================================================================================
  302. Func _ArrayCombinations(Const ByRef $aArray, $iSet, $sDelimiter = "")
  303. If $sDelimiter = Default Then $sDelimiter = ""
  304. If Not IsArray($aArray) Then Return SetError(1, 0, 0)
  305. If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, 0)
  306. Local $iN = UBound($aArray)
  307. Local $iR = $iSet
  308. Local $aIdx[$iR]
  309. For $i = 0 To $iR - 1
  310. $aIdx[$i] = $i
  311. Next
  312. Local $iTotal = __Array_Combinations($iN, $iR)
  313. Local $iLeft = $iTotal
  314. Local $aResult[$iTotal + 1]
  315. $aResult[0] = $iTotal
  316. Local $iCount = 1
  317. While $iLeft > 0
  318. __Array_GetNext($iN, $iR, $iLeft, $iTotal, $aIdx)
  319. For $i = 0 To $iSet - 1
  320. $aResult[$iCount] &= $aArray[$aIdx[$i]] & $sDelimiter
  321. Next
  322. If $sDelimiter <> "" Then $aResult[$iCount] = StringTrimRight($aResult[$iCount], 1)
  323. $iCount += 1
  324. WEnd
  325. Return $aResult
  326. EndFunc ;==>_ArrayCombinations
  327. ; #FUNCTION# ====================================================================================================================
  328. ; Author ........: Ultima
  329. ; Modified.......: Partypooper - added target start index; Melba23 - add 2D support
  330. ; ===============================================================================================================================
  331. Func _ArrayConcatenate(ByRef $aArrayTarget, Const ByRef $aArraySource, $iStart = 0)
  332. If $iStart = Default Then $iStart = 0
  333. If Not IsArray($aArrayTarget) Then Return SetError(1, 0, -1)
  334. If Not IsArray($aArraySource) Then Return SetError(2, 0, -1)
  335. Local $iDim_Total_Tgt = UBound($aArrayTarget, $UBOUND_DIMENSIONS)
  336. Local $iDim_Total_Src = UBound($aArraySource, $UBOUND_DIMENSIONS)
  337. Local $iDim_1_Tgt = UBound($aArrayTarget, $UBOUND_ROWS)
  338. Local $iDim_1_Src = UBound($aArraySource, $UBOUND_ROWS)
  339. If $iStart < 0 Or $iStart > $iDim_1_Src - 1 Then Return SetError(6, 0, -1)
  340. Switch $iDim_Total_Tgt
  341. Case 1
  342. If $iDim_Total_Src <> 1 Then Return SetError(4, 0, -1)
  343. ReDim $aArrayTarget[$iDim_1_Tgt + $iDim_1_Src - $iStart]
  344. For $i = $iStart To $iDim_1_Src - 1
  345. $aArrayTarget[$iDim_1_Tgt + $i - $iStart] = $aArraySource[$i]
  346. Next
  347. Case 2
  348. If $iDim_Total_Src <> 2 Then Return SetError(4, 0, -1)
  349. Local $iDim_2_Tgt = UBound($aArrayTarget, $UBOUND_COLUMNS)
  350. If UBound($aArraySource, $UBOUND_COLUMNS) <> $iDim_2_Tgt Then Return SetError(5, 0, -1)
  351. ReDim $aArrayTarget[$iDim_1_Tgt + $iDim_1_Src - $iStart][$iDim_2_Tgt]
  352. For $i = $iStart To $iDim_1_Src - 1
  353. For $j = 0 To $iDim_2_Tgt - 1
  354. $aArrayTarget[$iDim_1_Tgt + $i - $iStart][$j] = $aArraySource[$i][$j]
  355. Next
  356. Next
  357. Case Else
  358. Return SetError(3, 0, -1)
  359. EndSwitch
  360. Return UBound($aArrayTarget, $UBOUND_ROWS)
  361. EndFunc ;==>_ArrayConcatenate
  362. ; #FUNCTION# ====================================================================================================================
  363. ; Author ........: Cephas <cephas at clergy dot net>
  364. ; Modified.......: Jos - array passed ByRef, jaberwocky6669, Melba23 - added 2D support & multiple deletion
  365. ; ===============================================================================================================================
  366. Func _ArrayDelete(ByRef $aArray, $vRange)
  367. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  368. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  369. If IsArray($vRange) Then
  370. If UBound($vRange, $UBOUND_DIMENSIONS) <> 1 Or UBound($vRange, $UBOUND_ROWS) < 2 Then Return SetError(4, 0, -1)
  371. Else
  372. ; Expand range
  373. Local $iNumber, $aSplit_1, $aSplit_2
  374. $vRange = StringStripWS($vRange, 8)
  375. $aSplit_1 = StringSplit($vRange, ";")
  376. $vRange = ""
  377. For $i = 1 To $aSplit_1[0]
  378. ; Check for correct range syntax
  379. If Not StringRegExp($aSplit_1[$i], "^\d+(-\d+)?$") Then Return SetError(3, 0, -1)
  380. $aSplit_2 = StringSplit($aSplit_1[$i], "-")
  381. Switch $aSplit_2[0]
  382. Case 1
  383. $vRange &= $aSplit_2[1] & ";"
  384. Case 2
  385. If Number($aSplit_2[2]) >= Number($aSplit_2[1]) Then
  386. $iNumber = $aSplit_2[1] - 1
  387. Do
  388. $iNumber += 1
  389. $vRange &= $iNumber & ";"
  390. Until $iNumber = $aSplit_2[2]
  391. EndIf
  392. EndSwitch
  393. Next
  394. $vRange = StringSplit(StringTrimRight($vRange, 1), ";")
  395. EndIf
  396. If $vRange[1] < 0 Or $vRange[$vRange[0]] > $iDim_1 Then Return SetError(5, 0, -1)
  397. ; Remove rows
  398. Local $iCopyTo_Index = 0
  399. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  400. Case 1
  401. ; Loop through array flagging elements to be deleted
  402. For $i = 1 To $vRange[0]
  403. $aArray[$vRange[$i]] = ChrW(0xFAB1)
  404. Next
  405. ; Now copy rows to keep to fill deleted rows
  406. For $iReadFrom_Index = 0 To $iDim_1
  407. If $aArray[$iReadFrom_Index] == ChrW(0xFAB1) Then
  408. ContinueLoop
  409. Else
  410. If $iReadFrom_Index <> $iCopyTo_Index Then
  411. $aArray[$iCopyTo_Index] = $aArray[$iReadFrom_Index]
  412. EndIf
  413. $iCopyTo_Index += 1
  414. EndIf
  415. Next
  416. ReDim $aArray[$iDim_1 - $vRange[0] + 1]
  417. Case 2
  418. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  419. ; Loop through array flagging elements to be deleted
  420. For $i = 1 To $vRange[0]
  421. $aArray[$vRange[$i]][0] = ChrW(0xFAB1)
  422. Next
  423. ; Now copy rows to keep to fill deleted rows
  424. For $iReadFrom_Index = 0 To $iDim_1
  425. If $aArray[$iReadFrom_Index][0] == ChrW(0xFAB1) Then
  426. ContinueLoop
  427. Else
  428. If $iReadFrom_Index <> $iCopyTo_Index Then
  429. For $j = 0 To $iDim_2
  430. $aArray[$iCopyTo_Index][$j] = $aArray[$iReadFrom_Index][$j]
  431. Next
  432. EndIf
  433. $iCopyTo_Index += 1
  434. EndIf
  435. Next
  436. ReDim $aArray[$iDim_1 - $vRange[0] + 1][$iDim_2 + 1]
  437. Case Else
  438. Return SetError(2, 0, False)
  439. EndSwitch
  440. Return UBound($aArray, $UBOUND_ROWS)
  441. EndFunc ;==>_ArrayDelete
  442. ; #FUNCTION# ====================================================================================================================
  443. ; Author ........: randallc, Ultima
  444. ; Modified.......: Gary Frost (gafrost), Ultima, Zedna, jpm, Melba23, AZJIO, UEZ
  445. ; ===============================================================================================================================
  446. Func _ArrayDisplay(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default)
  447. #forceref $vUser_Separator
  448. Local $iRet = __ArrayDisplay_Share($aArray, $sTitle, $sArrayRange, $iFlags, Default, $sHeader, $iMax_ColWidth, 0, False)
  449. Return SetError(@error, @extended, $iRet)
  450. EndFunc ;==>_ArrayDisplay
  451. ; #FUNCTION# ====================================================================================================================
  452. ; Author ........: Melba23
  453. ; Modified.......:
  454. ; ===============================================================================================================================
  455. Func _ArrayExtract(Const ByRef $aArray, $iStart_Row = -1, $iEnd_Row = -1, $iStart_Col = -1, $iEnd_Col = -1)
  456. If $iStart_Row = Default Then $iStart_Row = -1
  457. If $iEnd_Row = Default Then $iEnd_Row = -1
  458. If $iStart_Col = Default Then $iStart_Col = -1
  459. If $iEnd_Col = Default Then $iEnd_Col = -1
  460. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  461. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  462. If $iEnd_Row = -1 Then $iEnd_Row = $iDim_1
  463. If $iStart_Row = -1 Then $iStart_Row = 0
  464. If $iStart_Row < -1 Or $iEnd_Row < -1 Then Return SetError(3, 0, -1)
  465. If $iStart_Row > $iDim_1 Or $iEnd_Row > $iDim_1 Then Return SetError(3, 0, -1)
  466. If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
  467. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  468. Case 1
  469. Local $aRetArray[$iEnd_Row - $iStart_Row + 1]
  470. For $i = 0 To $iEnd_Row - $iStart_Row
  471. $aRetArray[$i] = $aArray[$i + $iStart_Row]
  472. Next
  473. Return $aRetArray
  474. Case 2
  475. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  476. If $iEnd_Col = -1 Then $iEnd_Col = $iDim_2
  477. If $iStart_Col = -1 Then $iStart_Col = 0
  478. If $iStart_Col < -1 Or $iEnd_Col < -1 Then Return SetError(5, 0, -1)
  479. If $iStart_Col > $iDim_2 Or $iEnd_Col > $iDim_2 Then Return SetError(5, 0, -1)
  480. If $iStart_Col > $iEnd_Col Then Return SetError(6, 0, -1)
  481. If $iStart_Col = $iEnd_Col Then
  482. Local $aRetArray[$iEnd_Row - $iStart_Row + 1]
  483. Else
  484. Local $aRetArray[$iEnd_Row - $iStart_Row + 1][$iEnd_Col - $iStart_Col + 1]
  485. EndIf
  486. For $i = 0 To $iEnd_Row - $iStart_Row
  487. For $j = 0 To $iEnd_Col - $iStart_Col
  488. If $iStart_Col = $iEnd_Col Then
  489. $aRetArray[$i] = $aArray[$i + $iStart_Row][$j + $iStart_Col]
  490. Else
  491. $aRetArray[$i][$j] = $aArray[$i + $iStart_Row][$j + $iStart_Col]
  492. EndIf
  493. Next
  494. Next
  495. Return $aRetArray
  496. Case Else
  497. Return SetError(2, 0, -1)
  498. EndSwitch
  499. Return 1
  500. EndFunc ;==>_ArrayExtract
  501. ; #FUNCTION# ====================================================================================================================
  502. ; Author ........: GEOSoft, Ultima
  503. ; Modified.......:
  504. ; ===============================================================================================================================
  505. Func _ArrayFindAll(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iSubItem = 0, $bRow = False)
  506. If $iStart = Default Then $iStart = 0
  507. If $iEnd = Default Then $iEnd = 0
  508. If $iCase = Default Then $iCase = 0
  509. If $iCompare = Default Then $iCompare = 0
  510. If $iSubItem = Default Then $iSubItem = 0
  511. If $bRow = Default Then $bRow = False
  512. $iStart = _ArraySearch($aArray, $vValue, $iStart, $iEnd, $iCase, $iCompare, 1, $iSubItem, $bRow)
  513. If @error Then Return SetError(@error, 0, -1)
  514. Local $iIndex = 0, $avResult[UBound($aArray, ($bRow ? $UBOUND_COLUMNS : $UBOUND_ROWS))] ; Set dimension for Column/Row
  515. Do
  516. $avResult[$iIndex] = $iStart
  517. $iIndex += 1
  518. $iStart = _ArraySearch($aArray, $vValue, $iStart + 1, $iEnd, $iCase, $iCompare, 1, $iSubItem, $bRow)
  519. Until @error
  520. ReDim $avResult[$iIndex]
  521. Return $avResult
  522. EndFunc ;==>_ArrayFindAll
  523. ; #FUNCTION# ====================================================================================================================
  524. ; Author ........: Jos
  525. ; Modified.......: Ultima - code cleanup; Melba23 - element position check, 2D support & multiple insertions
  526. ; ===============================================================================================================================
  527. Func _ArrayInsert(ByRef $aArray, $vRange, $vValue = "", $iStart = 0, $sDelim_Item = "|", $sDelim_Row = @CRLF, $iForce = $ARRAYFILL_FORCE_DEFAULT)
  528. If $vValue = Default Then $vValue = ""
  529. If $iStart = Default Then $iStart = 0
  530. If $sDelim_Item = Default Then $sDelim_Item = "|"
  531. If $sDelim_Row = Default Then $sDelim_Row = @CRLF
  532. If $iForce = Default Then $iForce = $ARRAYFILL_FORCE_DEFAULT
  533. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  534. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  535. Local $hDataType = 0
  536. Switch $iForce
  537. Case $ARRAYFILL_FORCE_INT
  538. $hDataType = Int
  539. Case $ARRAYFILL_FORCE_NUMBER
  540. $hDataType = Number
  541. Case $ARRAYFILL_FORCE_PTR
  542. $hDataType = Ptr
  543. Case $ARRAYFILL_FORCE_HWND
  544. $hDataType = Hwnd
  545. Case $ARRAYFILL_FORCE_STRING
  546. $hDataType = String
  547. EndSwitch
  548. Local $aSplit_1, $aSplit_2
  549. If IsArray($vRange) Then
  550. If UBound($vRange, $UBOUND_DIMENSIONS) <> 1 Or UBound($vRange, $UBOUND_ROWS) < 2 Then Return SetError(4, 0, -1)
  551. Else
  552. ; Expand range
  553. Local $iNumber
  554. $vRange = StringStripWS($vRange, 8)
  555. $aSplit_1 = StringSplit($vRange, ";")
  556. $vRange = ""
  557. For $i = 1 To $aSplit_1[0]
  558. ; Check for correct range syntax
  559. If Not StringRegExp($aSplit_1[$i], "^\d+(-\d+)?$") Then Return SetError(3, 0, -1)
  560. $aSplit_2 = StringSplit($aSplit_1[$i], "-")
  561. Switch $aSplit_2[0]
  562. Case 1
  563. $vRange &= $aSplit_2[1] & ";"
  564. Case 2
  565. If Number($aSplit_2[2]) >= Number($aSplit_2[1]) Then
  566. $iNumber = $aSplit_2[1] - 1
  567. Do
  568. $iNumber += 1
  569. $vRange &= $iNumber & ";"
  570. Until $iNumber = $aSplit_2[2]
  571. EndIf
  572. EndSwitch
  573. Next
  574. $vRange = StringSplit(StringTrimRight($vRange, 1), ";")
  575. EndIf
  576. If $vRange[1] < 0 Or $vRange[$vRange[0]] > $iDim_1 Then Return SetError(5, 0, -1)
  577. For $i = 2 To $vRange[0]
  578. If $vRange[$i] < $vRange[$i - 1] Then Return SetError(3, 0, -1)
  579. Next
  580. Local $iCopyTo_Index = $iDim_1 + $vRange[0]
  581. Local $iInsertPoint_Index = $vRange[0]
  582. ; Get lowest insert point
  583. Local $iInsert_Index = $vRange[$iInsertPoint_Index]
  584. ; Insert lines
  585. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  586. Case 1
  587. If $iForce = $ARRAYFILL_FORCE_SINGLEITEM Then
  588. ReDim $aArray[$iDim_1 + $vRange[0] + 1]
  589. For $iReadFromIndex = $iDim_1 To 0 Step -1
  590. ; Copy existing elements
  591. $aArray[$iCopyTo_Index] = $aArray[$iReadFromIndex]
  592. ; Move up array
  593. $iCopyTo_Index -= 1
  594. ; Get next insert point
  595. $iInsert_Index = $vRange[$iInsertPoint_Index]
  596. While $iReadFromIndex = $iInsert_Index
  597. ; Insert new item
  598. $aArray[$iCopyTo_Index] = $vValue
  599. ; Move up array
  600. $iCopyTo_Index -= 1
  601. ; Reset insert index
  602. $iInsertPoint_Index -= 1
  603. If $iInsertPoint_Index < 1 Then ExitLoop 2
  604. ; Get next insert point
  605. $iInsert_Index = $vRange[$iInsertPoint_Index]
  606. WEnd
  607. Next
  608. Return $iDim_1 + $vRange[0] + 1
  609. EndIf
  610. ReDim $aArray[$iDim_1 + $vRange[0] + 1]
  611. If IsArray($vValue) Then
  612. If UBound($vValue, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(5, 0, -1)
  613. $hDataType = 0
  614. Else
  615. Local $aTmp = StringSplit($vValue, $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  616. If UBound($aTmp, $UBOUND_ROWS) = 1 Then
  617. $aTmp[0] = $vValue
  618. $hDataType = 0
  619. EndIf
  620. $vValue = $aTmp
  621. EndIf
  622. For $iReadFromIndex = $iDim_1 To 0 Step -1
  623. ; Copy existing elements
  624. $aArray[$iCopyTo_Index] = $aArray[$iReadFromIndex]
  625. ; Move up array
  626. $iCopyTo_Index -= 1
  627. ; Get next insert point
  628. $iInsert_Index = $vRange[$iInsertPoint_Index]
  629. While $iReadFromIndex = $iInsert_Index
  630. ; Insert new item
  631. If $iInsertPoint_Index <= UBound($vValue, $UBOUND_ROWS) Then
  632. If IsFunc($hDataType) Then
  633. $aArray[$iCopyTo_Index] = $hDataType($vValue[$iInsertPoint_Index - 1])
  634. Else
  635. $aArray[$iCopyTo_Index] = $vValue[$iInsertPoint_Index - 1]
  636. EndIf
  637. Else
  638. $aArray[$iCopyTo_Index] = ""
  639. EndIf
  640. ; Move up array
  641. $iCopyTo_Index -= 1
  642. ; Reset insert index
  643. $iInsertPoint_Index -= 1
  644. If $iInsertPoint_Index = 0 Then ExitLoop 2
  645. ; Get next insert point
  646. $iInsert_Index = $vRange[$iInsertPoint_Index]
  647. WEnd
  648. Next
  649. Case 2
  650. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
  651. If $iStart < 0 Or $iStart > $iDim_2 - 1 Then Return SetError(6, 0, -1)
  652. Local $iValDim_1, $iValDim_2
  653. If IsArray($vValue) Then
  654. If UBound($vValue, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(7, 0, -1)
  655. $iValDim_1 = UBound($vValue, $UBOUND_ROWS)
  656. $iValDim_2 = UBound($vValue, $UBOUND_COLUMNS)
  657. $hDataType = 0
  658. Else
  659. ; Convert string to 2D array
  660. $aSplit_1 = StringSplit($vValue, $sDelim_Row, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  661. $iValDim_1 = UBound($aSplit_1, $UBOUND_ROWS)
  662. StringReplace($aSplit_1[0], $sDelim_Item, "")
  663. $iValDim_2 = @extended + 1
  664. Local $aTmp[$iValDim_1][$iValDim_2]
  665. For $i = 0 To $iValDim_1 - 1
  666. $aSplit_2 = StringSplit($aSplit_1[$i], $sDelim_Item, $STR_NOCOUNT + $STR_ENTIRESPLIT)
  667. For $j = 0 To $iValDim_2 - 1
  668. $aTmp[$i][$j] = $aSplit_2[$j]
  669. Next
  670. Next
  671. $vValue = $aTmp
  672. EndIf
  673. ; Check if too many columns to fit
  674. If UBound($vValue, $UBOUND_COLUMNS) + $iStart > UBound($aArray, $UBOUND_COLUMNS) Then Return SetError(8, 0, -1)
  675. ReDim $aArray[$iDim_1 + $vRange[0] + 1][$iDim_2]
  676. For $iReadFromIndex = $iDim_1 To 0 Step -1
  677. ; Copy existing elements
  678. For $j = 0 To $iDim_2 - 1
  679. $aArray[$iCopyTo_Index][$j] = $aArray[$iReadFromIndex][$j]
  680. Next
  681. ; Move up array
  682. $iCopyTo_Index -= 1
  683. ; Get next insert point
  684. $iInsert_Index = $vRange[$iInsertPoint_Index]
  685. While $iReadFromIndex = $iInsert_Index
  686. ; Insert new item
  687. For $j = 0 To $iDim_2 - 1
  688. If $j < $iStart Then
  689. $aArray[$iCopyTo_Index][$j] = ""
  690. ElseIf $j - $iStart > $iValDim_2 - 1 Then
  691. $aArray[$iCopyTo_Index][$j] = ""
  692. Else
  693. If $iInsertPoint_Index - 1 < $iValDim_1 Then
  694. If IsFunc($hDataType) Then
  695. $aArray[$iCopyTo_Index][$j] = $hDataType($vValue[$iInsertPoint_Index - 1][$j - $iStart])
  696. Else
  697. $aArray[$iCopyTo_Index][$j] = $vValue[$iInsertPoint_Index - 1][$j - $iStart]
  698. EndIf
  699. Else
  700. $aArray[$iCopyTo_Index][$j] = ""
  701. EndIf
  702. EndIf
  703. Next
  704. ; Move up array
  705. $iCopyTo_Index -= 1
  706. ; Reset insert index
  707. $iInsertPoint_Index -= 1
  708. If $iInsertPoint_Index = 0 Then ExitLoop 2
  709. ; Get next insert point
  710. $iInsert_Index = $vRange[$iInsertPoint_Index]
  711. WEnd
  712. Next
  713. Case Else
  714. Return SetError(2, 0, -1)
  715. EndSwitch
  716. Return UBound($aArray, $UBOUND_ROWS)
  717. EndFunc ;==>_ArrayInsert
  718. ; #FUNCTION# ====================================================================================================================
  719. ; Author ........: Cephas <cephas at clergy dot net>
  720. ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic, Ultima - added $iEnd parameter, code cleanup; Melba23 - Added 2D support
  721. ; ===============================================================================================================================
  722. Func _ArrayMax(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
  723. Local $iResult = _ArrayMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem)
  724. If @error Then Return SetError(@error, 0, "")
  725. If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then
  726. Return $aArray[$iResult]
  727. Else
  728. Return $aArray[$iResult][$iSubItem]
  729. EndIf
  730. EndFunc ;==>_ArrayMax
  731. ; #FUNCTION# ====================================================================================================================
  732. ; Author ........: Cephas <cephas at clergy dot net>
  733. ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic; Melba23 - Added 2D support; guinness - Reduced duplicate code.
  734. ; ===============================================================================================================================
  735. Func _ArrayMaxIndex(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
  736. If $iCompNumeric = Default Then $iCompNumeric = 0
  737. If $iStart = Default Then $iStart = -1
  738. If $iEnd = Default Then $iEnd = -1
  739. If $iSubItem = Default Then $iSubItem = 0
  740. Local $iRet = __Array_MinMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem, __Array_GreaterThan) ; Pass a delegate function to check if value1 > value2.
  741. Return SetError(@error, 0, $iRet)
  742. EndFunc ;==>_ArrayMaxIndex
  743. ; #FUNCTION# ====================================================================================================================
  744. ; Author ........: Cephas <cephas at clergy dot net>
  745. ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic, Ultima - added $iEnd parameter, code cleanup; Melba23 - Added 2D support
  746. ; ===============================================================================================================================
  747. Func _ArrayMin(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
  748. Local $iResult = _ArrayMinIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem)
  749. If @error Then Return SetError(@error, 0, "")
  750. If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then
  751. Return $aArray[$iResult]
  752. Else
  753. Return $aArray[$iResult][$iSubItem]
  754. EndIf
  755. EndFunc ;==>_ArrayMin
  756. ; #FUNCTION# ====================================================================================================================
  757. ; Author ........: Cephas <cephas at clergy dot net>
  758. ; Modified.......: Jos - Added $iCompNumeric and $iStart parameters and logic; Melba23 - Added 2D support; guinness - Reduced duplicate code.
  759. ; ===============================================================================================================================
  760. Func _ArrayMinIndex(Const ByRef $aArray, $iCompNumeric = 0, $iStart = -1, $iEnd = -1, $iSubItem = 0)
  761. If $iCompNumeric = Default Then $iCompNumeric = 0
  762. If $iStart = Default Then $iStart = -1
  763. If $iEnd = Default Then $iEnd = -1
  764. If $iSubItem = Default Then $iSubItem = 0
  765. Local $iRet = __Array_MinMaxIndex($aArray, $iCompNumeric, $iStart, $iEnd, $iSubItem, __Array_LessThan) ; Pass a delegate function to check if value1 < value2.
  766. Return SetError(@error, 0, $iRet)
  767. EndFunc ;==>_ArrayMinIndex
  768. ; #FUNCTION# ====================================================================================================================
  769. ; Author ........: Erik Pilsits
  770. ; Modified.......: Melba23 - added support for empty arrays
  771. ; ===============================================================================================================================
  772. Func _ArrayPermute(ByRef $aArray, $sDelimiter = "")
  773. If $sDelimiter = Default Then $sDelimiter = ""
  774. If Not IsArray($aArray) Then Return SetError(1, 0, 0)
  775. If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, 0)
  776. Local $iSize = UBound($aArray), $iFactorial = 1, $aIdx[$iSize], $aResult[1], $iCount = 1
  777. If UBound($aArray) Then
  778. For $i = 0 To $iSize - 1
  779. $aIdx[$i] = $i
  780. Next
  781. For $i = $iSize To 1 Step -1
  782. $iFactorial *= $i
  783. Next
  784. ReDim $aResult[$iFactorial + 1]
  785. $aResult[0] = $iFactorial
  786. __Array_ExeterInternal($aArray, 0, $iSize, $sDelimiter, $aIdx, $aResult, $iCount)
  787. Else
  788. $aResult[0] = 0
  789. EndIf
  790. Return $aResult
  791. EndFunc ;==>_ArrayPermute
  792. ; #FUNCTION# ====================================================================================================================
  793. ; Author ........: Cephas <cephas at clergy dot net>
  794. ; Modified.......: Ultima - code cleanup; Melba23 - added support for empty arrays
  795. ; ===============================================================================================================================
  796. Func _ArrayPop(ByRef $aArray)
  797. If (Not IsArray($aArray)) Then Return SetError(1, 0, "")
  798. If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(2, 0, "")
  799. Local $iUBound = UBound($aArray) - 1
  800. If $iUBound = -1 Then Return SetError(3, 0, "")
  801. Local $sLastVal = $aArray[$iUBound]
  802. ; Remove last item
  803. If $iUBound > -1 Then
  804. ReDim $aArray[$iUBound]
  805. EndIf
  806. ; Return last item
  807. Return $sLastVal
  808. EndFunc ;==>_ArrayPop
  809. ; #FUNCTION# ====================================================================================================================
  810. ; Author ........: Helias Gerassimou(hgeras), Ultima - code cleanup/rewrite (major optimization), fixed support for $vValue as an array
  811. ; Modified.......:
  812. ; ===============================================================================================================================
  813. Func _ArrayPush(ByRef $aArray, $vValue, $iDirection = 0)
  814. If $iDirection = Default Then $iDirection = 0
  815. If (Not IsArray($aArray)) Then Return SetError(1, 0, 0)
  816. If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(3, 0, 0)
  817. Local $iUBound = UBound($aArray) - 1
  818. If IsArray($vValue) Then ; $vValue is an array
  819. Local $iUBoundS = UBound($vValue)
  820. If ($iUBoundS - 1) > $iUBound Then Return SetError(2, 0, 0)
  821. ; $vValue is an array smaller than $aArray
  822. If $iDirection Then ; slide right, add to front
  823. For $i = $iUBound To $iUBoundS Step -1
  824. $aArray[$i] = $aArray[$i - $iUBoundS]
  825. Next
  826. For $i = 0 To $iUBoundS - 1
  827. $aArray[$i] = $vValue[$i]
  828. Next
  829. Else ; slide left, add to end
  830. For $i = 0 To $iUBound - $iUBoundS
  831. $aArray[$i] = $aArray[$i + $iUBoundS]
  832. Next
  833. For $i = 0 To $iUBoundS - 1
  834. $aArray[$i + $iUBound - $iUBoundS + 1] = $vValue[$i]
  835. Next
  836. EndIf
  837. Else
  838. ; Check for empty array
  839. If $iUBound > -1 Then
  840. If $iDirection Then ; slide right, add to front
  841. For $i = $iUBound To 1 Step -1
  842. $aArray[$i] = $aArray[$i - 1]
  843. Next
  844. $aArray[0] = $vValue
  845. Else ; slide left, add to end
  846. For $i = 0 To $iUBound - 1
  847. $aArray[$i] = $aArray[$i + 1]
  848. Next
  849. $aArray[$iUBound] = $vValue
  850. EndIf
  851. EndIf
  852. EndIf
  853. Return 1
  854. EndFunc ;==>_ArrayPush
  855. ; #FUNCTION# ====================================================================================================================
  856. ; Author ........: Brian Keene
  857. ; Modified.......: Jos - added $iStart parameter and logic; Tylo - added $iEnd parameter and rewrote it for speed
  858. ; ===============================================================================================================================
  859. Func _ArrayReverse(ByRef $aArray, $iStart = 0, $iEnd = 0)
  860. If $iStart = Default Then $iStart = 0
  861. If $iEnd = Default Then $iEnd = 0
  862. If Not IsArray($aArray) Then Return SetError(1, 0, 0)
  863. If UBound($aArray, $UBOUND_DIMENSIONS) <> 1 Then Return SetError(3, 0, 0)
  864. If Not UBound($aArray) Then Return SetError(4, 0, 0)
  865. Local $vTmp, $iUBound = UBound($aArray) - 1
  866. ; Bounds checking
  867. If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
  868. If $iStart < 0 Then $iStart = 0
  869. If $iStart > $iEnd Then Return SetError(2, 0, 0)
  870. ; Reverse
  871. For $i = $iStart To Int(($iStart + $iEnd - 1) / 2)
  872. $vTmp = $aArray[$i]
  873. $aArray[$i] = $aArray[$iEnd]
  874. $aArray[$iEnd] = $vTmp
  875. $iEnd -= 1
  876. Next
  877. Return 1
  878. EndFunc ;==>_ArrayReverse
  879. ; #FUNCTION# ====================================================================================================================
  880. ; Author ........: Michael Michta <MetalGX91 at GMail dot com>
  881. ; 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
  882. ; ===============================================================================================================================
  883. Func _ArraySearch(Const ByRef $aArray, $vValue, $iStart = 0, $iEnd = 0, $iCase = 0, $iCompare = 0, $iForward = 1, $iSubItem = -1, $bRow = False)
  884. If $iStart = Default Then $iStart = 0
  885. If $iEnd = Default Then $iEnd = 0
  886. If $iCase = Default Then $iCase = 0
  887. If $iCompare = Default Then $iCompare = 0
  888. If $iForward = Default Then $iForward = 1
  889. If $iSubItem = Default Then $iSubItem = -1
  890. If $bRow = Default Then $bRow = False
  891. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  892. Local $iDim_1 = UBound($aArray) - 1
  893. If $iDim_1 = -1 Then Return SetError(3, 0, -1)
  894. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  895. ; Same var Type of comparison
  896. Local $bCompType = False
  897. If $iCompare = 2 Then
  898. $iCompare = 0
  899. $bCompType = True
  900. EndIf
  901. ; Bounds checking
  902. If $bRow Then
  903. If UBound($aArray, $UBOUND_DIMENSIONS) = 1 Then Return SetError(5, 0, -1)
  904. If $iEnd < 1 Or $iEnd > $iDim_2 Then $iEnd = $iDim_2
  905. If $iStart < 0 Then $iStart = 0
  906. If $iStart > $iEnd Then Return SetError(4, 0, -1)
  907. Else
  908. If $iEnd < 1 Or $iEnd > $iDim_1 Then $iEnd = $iDim_1
  909. If $iStart < 0 Then $iStart = 0
  910. If $iStart > $iEnd Then Return SetError(4, 0, -1)
  911. EndIf
  912. ; Direction (flip if $iForward = 0)
  913. Local $iStep = 1
  914. If Not $iForward Then
  915. Local $iTmp = $iStart
  916. $iStart = $iEnd
  917. $iEnd = $iTmp
  918. $iStep = -1
  919. EndIf
  920. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  921. Case 1 ; 1D array search
  922. If Not $iCompare Then
  923. If Not $iCase Then
  924. For $i = $iStart To $iEnd Step $iStep
  925. If $bCompType And VarGetType($aArray[$i]) <> VarGetType($vValue) Then ContinueLoop
  926. If $aArray[$i] = $vValue Then Return $i
  927. Next
  928. Else
  929. For $i = $iStart To $iEnd Step $iStep
  930. If $bCompType And VarGetType($aArray[$i]) <> VarGetType($vValue) Then ContinueLoop
  931. If $aArray[$i] == $vValue Then Return $i
  932. Next
  933. EndIf
  934. Else
  935. For $i = $iStart To $iEnd Step $iStep
  936. If $iCompare = 3 Then
  937. If StringRegExp($aArray[$i], $vValue) Then Return $i
  938. Else
  939. If StringInStr($aArray[$i], $vValue, $iCase) > 0 Then Return $i
  940. EndIf
  941. Next
  942. EndIf
  943. Case 2 ; 2D array search
  944. Local $iDim_Sub
  945. If $bRow Then
  946. ; Search rows
  947. $iDim_Sub = $iDim_1
  948. If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
  949. If $iSubItem < 0 Then
  950. ; will search for all Col
  951. $iSubItem = 0
  952. Else
  953. $iDim_Sub = $iSubItem
  954. EndIf
  955. Else
  956. ; Search columns
  957. $iDim_Sub = $iDim_2
  958. If $iSubItem > $iDim_Sub Then $iSubItem = $iDim_Sub
  959. If $iSubItem < 0 Then
  960. ; will search for all Col
  961. $iSubItem = 0
  962. Else
  963. $iDim_Sub = $iSubItem
  964. EndIf
  965. EndIf
  966. ; Now do the search
  967. For $j = $iSubItem To $iDim_Sub
  968. If Not $iCompare Then
  969. If Not $iCase Then
  970. For $i = $iStart To $iEnd Step $iStep
  971. If $bRow Then
  972. If $bCompType And VarGetType($aArray[$j][$i]) <> VarGetType($vValue) Then ContinueLoop
  973. If $aArray[$j][$i] = $vValue Then Return $i
  974. Else
  975. If $bCompType And VarGetType($aArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
  976. If $aArray[$i][$j] = $vValue Then Return $i
  977. EndIf
  978. Next
  979. Else
  980. For $i = $iStart To $iEnd Step $iStep
  981. If $bRow Then
  982. If $bCompType And VarGetType($aArray[$j][$i]) <> VarGetType($vValue) Then ContinueLoop
  983. If $aArray[$j][$i] == $vValue Then Return $i
  984. Else
  985. If $bCompType And VarGetType($aArray[$i][$j]) <> VarGetType($vValue) Then ContinueLoop
  986. If $aArray[$i][$j] == $vValue Then Return $i
  987. EndIf
  988. Next
  989. EndIf
  990. Else
  991. For $i = $iStart To $iEnd Step $iStep
  992. If $iCompare = 3 Then
  993. If $bRow Then
  994. If StringRegExp($aArray[$j][$i], $vValue) Then Return $i
  995. Else
  996. If StringRegExp($aArray[$i][$j], $vValue) Then Return $i
  997. EndIf
  998. Else
  999. If $bRow Then
  1000. If StringInStr($aArray[$j][$i], $vValue, $iCase) > 0 Then Return $i
  1001. Else
  1002. If StringInStr($aArray[$i][$j], $vValue, $iCase) > 0 Then Return $i
  1003. EndIf
  1004. EndIf
  1005. Next
  1006. EndIf
  1007. Next
  1008. Case Else
  1009. Return SetError(2, 0, -1)
  1010. EndSwitch
  1011. Return SetError(6, 0, -1)
  1012. EndFunc ;==>_ArraySearch
  1013. ; #FUNCTION# ====================================================================================================================
  1014. ; Author ........: Melba23
  1015. ; Modified.......:
  1016. ; ===============================================================================================================================
  1017. Func _ArrayShuffle(ByRef $aArray, $iStart_Row = 0, $iEnd_Row = 0, $iCol = -1)
  1018. ; Fisher–Yates algorithm
  1019. If $iStart_Row = Default Then $iStart_Row = 0
  1020. If $iEnd_Row = Default Then $iEnd_Row = 0
  1021. If $iCol = Default Then $iCol = -1
  1022. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  1023. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
  1024. If $iEnd_Row = 0 Then $iEnd_Row = $iDim_1 - 1
  1025. If $iStart_Row < 0 Or $iStart_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
  1026. If $iEnd_Row < 1 Or $iEnd_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
  1027. If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
  1028. Local $vTmp, $iRand
  1029. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1030. Case 1
  1031. For $i = $iEnd_Row To $iStart_Row + 1 Step -1
  1032. $iRand = Random($iStart_Row, $i, 1)
  1033. $vTmp = $aArray[$i]
  1034. $aArray[$i] = $aArray[$iRand]
  1035. $aArray[$iRand] = $vTmp
  1036. Next
  1037. Return 1
  1038. Case 2
  1039. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
  1040. If $iCol < -1 Or $iCol > $iDim_2 - 1 Then Return SetError(5, 0, -1)
  1041. Local $iCol_Start, $iCol_End
  1042. If $iCol = -1 Then
  1043. $iCol_Start = 0
  1044. $iCol_End = $iDim_2 - 1
  1045. Else
  1046. $iCol_Start = $iCol
  1047. $iCol_End = $iCol
  1048. EndIf
  1049. For $i = $iEnd_Row To $iStart_Row + 1 Step -1
  1050. $iRand = Random($iStart_Row, $i, 1)
  1051. For $j = $iCol_Start To $iCol_End
  1052. $vTmp = $aArray[$i][$j]
  1053. $aArray[$i][$j] = $aArray[$iRand][$j]
  1054. $aArray[$iRand][$j] = $vTmp
  1055. Next
  1056. Next
  1057. Return 1
  1058. Case Else
  1059. Return SetError(2, 0, -1)
  1060. EndSwitch
  1061. EndFunc ;==>_ArrayShuffle
  1062. ; #FUNCTION# ====================================================================================================================
  1063. ; Author ........: Jos
  1064. ; 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
  1065. ; ===============================================================================================================================
  1066. Func _ArraySort(ByRef $aArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iPivot = 0)
  1067. If $iDescending = Default Then $iDescending = 0
  1068. If $iStart = Default Then $iStart = 0
  1069. If $iEnd = Default Then $iEnd = 0
  1070. If $iSubItem = Default Then $iSubItem = 0
  1071. If $iPivot = Default Then $iPivot = 0
  1072. If Not IsArray($aArray) Then Return SetError(1, 0, 0)
  1073. Local $iUBound = UBound($aArray) - 1
  1074. If $iUBound = -1 Then Return SetError(5, 0, 0)
  1075. ; Bounds checking
  1076. If $iEnd = Default Then $iEnd = 0
  1077. If $iEnd < 1 Or $iEnd > $iUBound Or $iEnd = Default Then $iEnd = $iUBound
  1078. If $iStart < 0 Or $iStart = Default Then $iStart = 0
  1079. If $iStart > $iEnd Then Return SetError(2, 0, 0)
  1080. ; Sort
  1081. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1082. Case 1
  1083. If $iPivot Then ; Switch algorithms as required
  1084. __ArrayDualPivotSort($aArray, $iStart, $iEnd)
  1085. Else
  1086. __ArrayQuickSort1D($aArray, $iStart, $iEnd)
  1087. EndIf
  1088. If $iDescending Then _ArrayReverse($aArray, $iStart, $iEnd)
  1089. Case 2
  1090. If $iPivot Then Return SetError(6, 0, 0) ; Error if 2D array and $iPivot
  1091. Local $iSubMax = UBound($aArray, $UBOUND_COLUMNS) - 1
  1092. If $iSubItem > $iSubMax Then Return SetError(3, 0, 0)
  1093. If $iDescending Then
  1094. $iDescending = -1
  1095. Else
  1096. $iDescending = 1
  1097. EndIf
  1098. __ArrayQuickSort2D($aArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax)
  1099. Case Else
  1100. Return SetError(4, 0, 0)
  1101. EndSwitch
  1102. Return 1
  1103. EndFunc ;==>_ArraySort
  1104. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1105. ; Name...........: __ArrayQuickSort1D
  1106. ; Description ...: Helper function for sorting 1D arrays
  1107. ; Syntax.........: __ArrayQuickSort1D ( ByRef $aArray, ByRef $iStart, ByRef $iEnd )
  1108. ; Parameters ....: $aArray - Array to sort
  1109. ; $iStart - Index of array to start sorting at
  1110. ; $iEnd - Index of array to stop sorting at
  1111. ; Return values .: None
  1112. ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
  1113. ; Modified.......:
  1114. ; Remarks .......: For Internal Use Only
  1115. ; Related .......:
  1116. ; Link ..........:
  1117. ; Example .......:
  1118. ; ===============================================================================================================================
  1119. Func __ArrayQuickSort1D(ByRef $aArray, Const ByRef $iStart, Const ByRef $iEnd)
  1120. If $iEnd <= $iStart Then Return
  1121. Local $vTmp
  1122. ; InsertionSort (faster for smaller segments)
  1123. If ($iEnd - $iStart) < 15 Then
  1124. Local $vCur
  1125. For $i = $iStart + 1 To $iEnd
  1126. $vTmp = $aArray[$i]
  1127. If IsNumber($vTmp) Then
  1128. For $j = $i - 1 To $iStart Step -1
  1129. $vCur = $aArray[$j]
  1130. ; If $vTmp >= $vCur Then ExitLoop
  1131. If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop
  1132. $aArray[$j + 1] = $vCur
  1133. Next
  1134. Else
  1135. For $j = $i - 1 To $iStart Step -1
  1136. If (StringCompare($vTmp, $aArray[$j]) >= 0) Then ExitLoop
  1137. $aArray[$j + 1] = $aArray[$j]
  1138. Next
  1139. EndIf
  1140. $aArray[$j + 1] = $vTmp
  1141. Next
  1142. Return
  1143. EndIf
  1144. ; QuickSort
  1145. Local $L = $iStart, $R = $iEnd, $vPivot = $aArray[Int(($iStart + $iEnd) / 2)], $bNum = IsNumber($vPivot)
  1146. Do
  1147. If $bNum Then
  1148. ; While $aArray[$L] < $vPivot
  1149. While ($aArray[$L] < $vPivot And IsNumber($aArray[$L])) Or (Not IsNumber($aArray[$L]) And StringCompare($aArray[$L], $vPivot) < 0)
  1150. $L += 1
  1151. WEnd
  1152. ; While $aArray[$R] > $vPivot
  1153. While ($aArray[$R] > $vPivot And IsNumber($aArray[$R])) Or (Not IsNumber($aArray[$R]) And StringCompare($aArray[$R], $vPivot) > 0)
  1154. $R -= 1
  1155. WEnd
  1156. Else
  1157. While (StringCompare($aArray[$L], $vPivot) < 0)
  1158. $L += 1
  1159. WEnd
  1160. While (StringCompare($aArray[$R], $vPivot) > 0)
  1161. $R -= 1
  1162. WEnd
  1163. EndIf
  1164. ; Swap
  1165. If $L <= $R Then
  1166. $vTmp = $aArray[$L]
  1167. $aArray[$L] = $aArray[$R]
  1168. $aArray[$R] = $vTmp
  1169. $L += 1
  1170. $R -= 1
  1171. EndIf
  1172. Until $L > $R
  1173. __ArrayQuickSort1D($aArray, $iStart, $R)
  1174. __ArrayQuickSort1D($aArray, $L, $iEnd)
  1175. EndFunc ;==>__ArrayQuickSort1D
  1176. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1177. ; Name...........: __ArrayQuickSort2D
  1178. ; Description ...: Helper function for sorting 2D arrays
  1179. ; Syntax.........: __ArrayQuickSort2D ( ByRef $aArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax )
  1180. ; Parameters ....: $aArray - Array to sort
  1181. ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!)
  1182. ; $iStart - Index of array to start sorting at
  1183. ; $iEnd - Index of array to stop sorting at
  1184. ; $iSubItem - Sub-index to sort on in 2D arrays
  1185. ; $iSubMax - Maximum sub-index that array has
  1186. ; Return values .: None
  1187. ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima
  1188. ; Modified.......:
  1189. ; Remarks .......: For Internal Use Only
  1190. ; Related .......:
  1191. ; Link ..........:
  1192. ; Example .......:
  1193. ; ===============================================================================================================================
  1194. Func __ArrayQuickSort2D(ByRef $aArray, Const ByRef $iStep, Const ByRef $iStart, Const ByRef $iEnd, Const ByRef $iSubItem, Const ByRef $iSubMax)
  1195. If $iEnd <= $iStart Then Return
  1196. ; QuickSort
  1197. Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $aArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $bNum = IsNumber($vPivot)
  1198. Do
  1199. If $bNum Then
  1200. ; While $aArray[$L][$iSubItem] < $vPivot
  1201. 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)
  1202. $L += 1
  1203. WEnd
  1204. ; While $aArray[$R][$iSubItem] > $vPivot
  1205. 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)
  1206. $R -= 1
  1207. WEnd
  1208. Else
  1209. While ($iStep * StringCompare($aArray[$L][$iSubItem], $vPivot) < 0)
  1210. $L += 1
  1211. WEnd
  1212. While ($iStep * StringCompare($aArray[$R][$iSubItem], $vPivot) > 0)
  1213. $R -= 1
  1214. WEnd
  1215. EndIf
  1216. ; Swap
  1217. If $L <= $R Then
  1218. For $i = 0 To $iSubMax
  1219. $vTmp = $aArray[$L][$i]
  1220. $aArray[$L][$i] = $aArray[$R][$i]
  1221. $aArray[$R][$i] = $vTmp
  1222. Next
  1223. $L += 1
  1224. $R -= 1
  1225. EndIf
  1226. Until $L > $R
  1227. __ArrayQuickSort2D($aArray, $iStep, $iStart, $R, $iSubItem, $iSubMax)
  1228. __ArrayQuickSort2D($aArray, $iStep, $L, $iEnd, $iSubItem, $iSubMax)
  1229. EndFunc ;==>__ArrayQuickSort2D
  1230. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1231. ; Name...........: __ArrayDualPivotSort
  1232. ; Description ...: Helper function for sorting 1D arrays
  1233. ; Syntax.........: __ArrayDualPivotSort ( ByRef $aArray, $iPivot_Left, $iPivot_Right [, $bLeftMost = True ] )
  1234. ; Parameters ....: $aArray - Array to sort
  1235. ; $iPivot_Left - Index of the array to start sorting at
  1236. ; $iPivot_Right - Index of the array to stop sorting at
  1237. ; $bLeftMost - Indicates if this part is the leftmost in the range
  1238. ; Return values .: None
  1239. ; Author ........: Erik Pilsits
  1240. ; Modified.......: Melba23
  1241. ; Remarks .......: For Internal Use Only
  1242. ; Related .......:
  1243. ; Link ..........:
  1244. ; Example .......:
  1245. ; ===============================================================================================================================
  1246. Func __ArrayDualPivotSort(ByRef $aArray, $iPivot_Left, $iPivot_Right, $bLeftMost = True)
  1247. If $iPivot_Left > $iPivot_Right Then Return
  1248. Local $iLength = $iPivot_Right - $iPivot_Left + 1
  1249. Local $i, $j, $k, $iAi, $iAk, $iA1, $iA2, $iLast
  1250. If $iLength < 45 Then ; Use insertion sort for small arrays - value chosen empirically
  1251. If $bLeftMost Then
  1252. $i = $iPivot_Left
  1253. While $i < $iPivot_Right
  1254. $j = $i
  1255. $iAi = $aArray[$i + 1]
  1256. While $iAi < $aArray[$j]
  1257. $aArray[$j + 1] = $aArray[$j]
  1258. $j -= 1
  1259. If $j + 1 = $iPivot_Left Then ExitLoop
  1260. WEnd
  1261. $aArray[$j + 1] = $iAi
  1262. $i += 1
  1263. WEnd
  1264. Else
  1265. While 1
  1266. If $iPivot_Left >= $iPivot_Right Then Return 1
  1267. $iPivot_Left += 1
  1268. If $aArray[$iPivot_Left] < $aArray[$iPivot_Left - 1] Then ExitLoop
  1269. WEnd
  1270. While 1
  1271. $k = $iPivot_Left
  1272. $iPivot_Left += 1
  1273. If $iPivot_Left > $iPivot_Right Then ExitLoop
  1274. $iA1 = $aArray[$k]
  1275. $iA2 = $aArray[$iPivot_Left]
  1276. If $iA1 < $iA2 Then
  1277. $iA2 = $iA1
  1278. $iA1 = $aArray[$iPivot_Left]
  1279. EndIf
  1280. $k -= 1
  1281. While $iA1 < $aArray[$k]
  1282. $aArray[$k + 2] = $aArray[$k]
  1283. $k -= 1
  1284. WEnd
  1285. $aArray[$k + 2] = $iA1
  1286. While $iA2 < $aArray[$k]
  1287. $aArray[$k + 1] = $aArray[$k]
  1288. $k -= 1
  1289. WEnd
  1290. $aArray[$k + 1] = $iA2
  1291. $iPivot_Left += 1
  1292. WEnd
  1293. $iLast = $aArray[$iPivot_Right]
  1294. $iPivot_Right -= 1
  1295. While $iLast < $aArray[$iPivot_Right]
  1296. $aArray[$iPivot_Right + 1] = $aArray[$iPivot_Right]
  1297. $iPivot_Right -= 1
  1298. WEnd
  1299. $aArray[$iPivot_Right + 1] = $iLast
  1300. EndIf
  1301. Return 1
  1302. EndIf
  1303. Local $iSeventh = BitShift($iLength, 3) + BitShift($iLength, 6) + 1
  1304. Local $iE1, $iE2, $iE3, $iE4, $iE5, $t
  1305. $iE3 = Ceiling(($iPivot_Left + $iPivot_Right) / 2)
  1306. $iE2 = $iE3 - $iSeventh
  1307. $iE1 = $iE2 - $iSeventh
  1308. $iE4 = $iE3 + $iSeventh
  1309. $iE5 = $iE4 + $iSeventh
  1310. If $aArray[$iE2] < $aArray[$iE1] Then
  1311. $t = $aArray[$iE2]
  1312. $aArray[$iE2] = $aArray[$iE1]
  1313. $aArray[$iE1] = $t
  1314. EndIf
  1315. If $aArray[$iE3] < $aArray[$iE2] Then
  1316. $t = $aArray[$iE3]
  1317. $aArray[$iE3] = $aArray[$iE2]
  1318. $aArray[$iE2] = $t
  1319. If $t < $aArray[$iE1] Then
  1320. $aArray[$iE2] = $aArray[$iE1]
  1321. $aArray[$iE1] = $t
  1322. EndIf
  1323. EndIf
  1324. If $aArray[$iE4] < $aArray[$iE3] Then
  1325. $t = $aArray[$iE4]
  1326. $aArray[$iE4] = $aArray[$iE3]
  1327. $aArray[$iE3] = $t
  1328. If $t < $aArray[$iE2] Then
  1329. $aArray[$iE3] = $aArray[$iE2]
  1330. $aArray[$iE2] = $t
  1331. If $t < $aArray[$iE1] Then
  1332. $aArray[$iE2] = $aArray[$iE1]
  1333. $aArray[$iE1] = $t
  1334. EndIf
  1335. EndIf
  1336. EndIf
  1337. If $aArray[$iE5] < $aArray[$iE4] Then
  1338. $t = $aArray[$iE5]
  1339. $aArray[$iE5] = $aArray[$iE4]
  1340. $aArray[$iE4] = $t
  1341. If $t < $aArray[$iE3] Then
  1342. $aArray[$iE4] = $aArray[$iE3]
  1343. $aArray[$iE3] = $t
  1344. If $t < $aArray[$iE2] Then
  1345. $aArray[$iE3] = $aArray[$iE2]
  1346. $aArray[$iE2] = $t
  1347. If $t < $aArray[$iE1] Then
  1348. $aArray[$iE2] = $aArray[$iE1]
  1349. $aArray[$iE1] = $t
  1350. EndIf
  1351. EndIf
  1352. EndIf
  1353. EndIf
  1354. Local $iLess = $iPivot_Left
  1355. Local $iGreater = $iPivot_Right
  1356. If (($aArray[$iE1] <> $aArray[$iE2]) And ($aArray[$iE2] <> $aArray[$iE3]) And ($aArray[$iE3] <> $aArray[$iE4]) And ($aArray[$iE4] <> $aArray[$iE5])) Then
  1357. Local $iPivot_1 = $aArray[$iE2]
  1358. Local $iPivot_2 = $aArray[$iE4]
  1359. $aArray[$iE2] = $aArray[$iPivot_Left]
  1360. $aArray[$iE4] = $aArray[$iPivot_Right]
  1361. Do
  1362. $iLess += 1
  1363. Until $aArray[$iLess] >= $iPivot_1
  1364. Do
  1365. $iGreater -= 1
  1366. Until $aArray[$iGreater] <= $iPivot_2
  1367. $k = $iLess
  1368. While $k <= $iGreater
  1369. $iAk = $aArray[$k]
  1370. If $iAk < $iPivot_1 Then
  1371. $aArray[$k] = $aArray[$iLess]
  1372. $aArray[$iLess] = $iAk
  1373. $iLess += 1
  1374. ElseIf $iAk > $iPivot_2 Then
  1375. While $aArray[$iGreater] > $iPivot_2
  1376. $iGreater -= 1
  1377. If $iGreater + 1 = $k Then ExitLoop 2
  1378. WEnd
  1379. If $aArray[$iGreater] < $iPivot_1 Then
  1380. $aArray[$k] = $aArray[$iLess]
  1381. $aArray[$iLess] = $aArray[$iGreater]
  1382. $iLess += 1
  1383. Else
  1384. $aArray[$k] = $aArray[$iGreater]
  1385. EndIf
  1386. $aArray[$iGreater] = $iAk
  1387. $iGreater -= 1
  1388. EndIf
  1389. $k += 1
  1390. WEnd
  1391. $aArray[$iPivot_Left] = $aArray[$iLess - 1]
  1392. $aArray[$iLess - 1] = $iPivot_1
  1393. $aArray[$iPivot_Right] = $aArray[$iGreater + 1]
  1394. $aArray[$iGreater + 1] = $iPivot_2
  1395. __ArrayDualPivotSort($aArray, $iPivot_Left, $iLess - 2, True)
  1396. __ArrayDualPivotSort($aArray, $iGreater + 2, $iPivot_Right, False)
  1397. If ($iLess < $iE1) And ($iE5 < $iGreater) Then
  1398. While $aArray[$iLess] = $iPivot_1
  1399. $iLess += 1
  1400. WEnd
  1401. While $aArray[$iGreater] = $iPivot_2
  1402. $iGreater -= 1
  1403. WEnd
  1404. $k = $iLess
  1405. While $k <= $iGreater
  1406. $iAk = $aArray[$k]
  1407. If $iAk = $iPivot_1 Then
  1408. $aArray[$k] = $aArray[$iLess]
  1409. $aArray[$iLess] = $iAk
  1410. $iLess += 1
  1411. ElseIf $iAk = $iPivot_2 Then
  1412. While $aArray[$iGreater] = $iPivot_2
  1413. $iGreater -= 1
  1414. If $iGreater + 1 = $k Then ExitLoop 2
  1415. WEnd
  1416. If $aArray[$iGreater] = $iPivot_1 Then
  1417. $aArray[$k] = $aArray[$iLess]
  1418. $aArray[$iLess] = $iPivot_1
  1419. $iLess += 1
  1420. Else
  1421. $aArray[$k] = $aArray[$iGreater]
  1422. EndIf
  1423. $aArray[$iGreater] = $iAk
  1424. $iGreater -= 1
  1425. EndIf
  1426. $k += 1
  1427. WEnd
  1428. EndIf
  1429. __ArrayDualPivotSort($aArray, $iLess, $iGreater, False)
  1430. Else
  1431. Local $iPivot = $aArray[$iE3]
  1432. $k = $iLess
  1433. While $k <= $iGreater
  1434. If $aArray[$k] = $iPivot Then
  1435. $k += 1
  1436. ContinueLoop
  1437. EndIf
  1438. $iAk = $aArray[$k]
  1439. If $iAk < $iPivot Then
  1440. $aArray[$k] = $aArray[$iLess]
  1441. $aArray[$iLess] = $iAk
  1442. $iLess += 1
  1443. Else
  1444. While $aArray[$iGreater] > $iPivot
  1445. $iGreater -= 1
  1446. WEnd
  1447. If $aArray[$iGreater] < $iPivot Then
  1448. $aArray[$k] = $aArray[$iLess]
  1449. $aArray[$iLess] = $aArray[$iGreater]
  1450. $iLess += 1
  1451. Else
  1452. $aArray[$k] = $iPivot
  1453. EndIf
  1454. $aArray[$iGreater] = $iAk
  1455. $iGreater -= 1
  1456. EndIf
  1457. $k += 1
  1458. WEnd
  1459. __ArrayDualPivotSort($aArray, $iPivot_Left, $iLess - 1, True)
  1460. __ArrayDualPivotSort($aArray, $iGreater + 1, $iPivot_Right, False)
  1461. EndIf
  1462. EndFunc ;==>__ArrayDualPivotSort
  1463. ; #FUNCTION# ====================================================================================================================
  1464. ; Author ........: Melba23
  1465. ; Modified.......:
  1466. ; ===============================================================================================================================
  1467. Func _ArraySwap(ByRef $aArray, $iIndex_1, $iIndex_2, $bCol = False, $iStart = -1, $iEnd = -1)
  1468. If $bCol = Default Then $bCol = False
  1469. If $iStart = Default Then $iStart = -1
  1470. If $iEnd = Default Then $iEnd = -1
  1471. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  1472. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  1473. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  1474. If $iDim_2 = -1 Then ; 1D array so force defaults
  1475. $bCol = False
  1476. $iStart = -1
  1477. $iEnd = -1
  1478. EndIf
  1479. ; Bounds check
  1480. If $iStart > $iEnd Then Return SetError(5, 0, -1)
  1481. If $bCol Then
  1482. If $iIndex_1 < 0 Or $iIndex_2 > $iDim_2 Then Return SetError(3, 0, -1)
  1483. If $iStart = -1 Then $iStart = 0
  1484. If $iEnd = -1 Then $iEnd = $iDim_1
  1485. Else
  1486. If $iIndex_1 < 0 Or $iIndex_2 > $iDim_1 Then Return SetError(3, 0, -1)
  1487. If $iStart = -1 Then $iStart = 0
  1488. If $iEnd = -1 Then $iEnd = $iDim_2
  1489. EndIf
  1490. Local $vTmp
  1491. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1492. Case 1
  1493. $vTmp = $aArray[$iIndex_1]
  1494. $aArray[$iIndex_1] = $aArray[$iIndex_2]
  1495. $aArray[$iIndex_2] = $vTmp
  1496. Case 2
  1497. If $iStart < -1 Or $iEnd < -1 Then Return SetError(4, 0, -1)
  1498. If $bCol Then
  1499. If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(4, 0, -1)
  1500. For $j = $iStart To $iEnd
  1501. $vTmp = $aArray[$j][$iIndex_1]
  1502. $aArray[$j][$iIndex_1] = $aArray[$j][$iIndex_2]
  1503. $aArray[$j][$iIndex_2] = $vTmp
  1504. Next
  1505. Else
  1506. If $iStart > $iDim_2 Or $iEnd > $iDim_2 Then Return SetError(4, 0, -1)
  1507. For $j = $iStart To $iEnd
  1508. $vTmp = $aArray[$iIndex_1][$j]
  1509. $aArray[$iIndex_1][$j] = $aArray[$iIndex_2][$j]
  1510. $aArray[$iIndex_2][$j] = $vTmp
  1511. Next
  1512. EndIf
  1513. Case Else
  1514. Return SetError(2, 0, -1)
  1515. EndSwitch
  1516. Return 1
  1517. EndFunc ;==>_ArraySwap
  1518. ; #FUNCTION# ====================================================================================================================
  1519. ; Author ........: Cephas <cephas at clergy dot net>
  1520. ; Modified.......: Jos - added $iStart parameter and logic, Ultima - added $iEnd parameter, make use of _ArrayToString() instead of duplicating efforts; Melba23 - added 2D support
  1521. ; ===============================================================================================================================
  1522. Func _ArrayToClip(Const ByRef $aArray, $sDelim_Col = "|", $iStart_Row = -1, $iEnd_Row = -1, $sDelim_Row = @CRLF, $iStart_Col = -1, $iEnd_Col = -1)
  1523. Local $sResult = _ArrayToString($aArray, $sDelim_Col, $iStart_Row, $iEnd_Row, $sDelim_Row, $iStart_Col, $iEnd_Col)
  1524. If @error Then Return SetError(@error, 0, 0)
  1525. If ClipPut($sResult) Then Return 1
  1526. Return SetError(-1, 0, 0)
  1527. EndFunc ;==>_ArrayToClip
  1528. ; #FUNCTION# ====================================================================================================================
  1529. ; Author ........: Brian Keene <brian_keene at yahoo dot com>, Valik - rewritten
  1530. ; Modified.......: Ultima - code cleanup; Melba23 - added support for empty and 2D arrays
  1531. ; ===============================================================================================================================
  1532. Func _ArrayToString(Const ByRef $aArray, $sDelim_Col = "|", $iStart_Row = -1, $iEnd_Row = -1, $sDelim_Row = @CRLF, $iStart_Col = -1, $iEnd_Col = -1)
  1533. If $sDelim_Col = Default Then $sDelim_Col = "|"
  1534. If $sDelim_Row = Default Then $sDelim_Row = @CRLF
  1535. If $iStart_Row = Default Then $iStart_Row = -1
  1536. If $iEnd_Row = Default Then $iEnd_Row = -1
  1537. If $iStart_Col = Default Then $iStart_Col = -1
  1538. If $iEnd_Col = Default Then $iEnd_Col = -1
  1539. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  1540. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  1541. If $iStart_Row = -1 Then $iStart_Row = 0
  1542. If $iEnd_Row = -1 Then $iEnd_Row = $iDim_1
  1543. If $iStart_Row < -1 Or $iEnd_Row < -1 Then Return SetError(3, 0, -1)
  1544. If $iStart_Row > $iDim_1 Or $iEnd_Row > $iDim_1 Then Return SetError(3, 0, "")
  1545. If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
  1546. Local $sRet = ""
  1547. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1548. Case 1
  1549. For $i = $iStart_Row To $iEnd_Row
  1550. $sRet &= $aArray[$i] & $sDelim_Col
  1551. Next
  1552. Return StringTrimRight($sRet, StringLen($sDelim_Col))
  1553. Case 2
  1554. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  1555. If $iStart_Col = -1 Then $iStart_Col = 0
  1556. If $iEnd_Col = -1 Then $iEnd_Col = $iDim_2
  1557. If $iStart_Col < -1 Or $iEnd_Col < -1 Then Return SetError(5, 0, -1)
  1558. If $iStart_Col > $iDim_2 Or $iEnd_Col > $iDim_2 Then Return SetError(5, 0, -1)
  1559. If $iStart_Col > $iEnd_Col Then Return SetError(6, 0, -1)
  1560. For $i = $iStart_Row To $iEnd_Row
  1561. For $j = $iStart_Col To $iEnd_Col
  1562. $sRet &= $aArray[$i][$j] & $sDelim_Col
  1563. Next
  1564. $sRet = StringTrimRight($sRet, StringLen($sDelim_Col)) & $sDelim_Row
  1565. Next
  1566. Return StringTrimRight($sRet, StringLen($sDelim_Row))
  1567. Case Else
  1568. Return SetError(2, 0, -1)
  1569. EndSwitch
  1570. Return 1
  1571. EndFunc ;==>_ArrayToString
  1572. ; #FUNCTION# ====================================================================================================================
  1573. ; Author ........: jchd
  1574. ; Modified.......: jpm, czardas
  1575. ; ===============================================================================================================================
  1576. Func _ArrayTranspose(ByRef $aArray)
  1577. Switch UBound($aArray, 0)
  1578. Case 0
  1579. Return SetError(2, 0, 0)
  1580. Case 1
  1581. Local $aTemp[1][UBound($aArray)]
  1582. For $i = 0 To UBound($aArray) - 1
  1583. $aTemp[0][$i] = $aArray[$i]
  1584. Next
  1585. $aArray = $aTemp
  1586. Case 2
  1587. Local $iDim_1 = UBound($aArray, 1), $iDim_2 = UBound($aArray, 2)
  1588. If $iDim_1 <> $iDim_2 Then
  1589. Local $aTemp[$iDim_2][$iDim_1]
  1590. For $i = 0 To $iDim_1 - 1
  1591. For $j = 0 To $iDim_2 - 1
  1592. $aTemp[$j][$i] = $aArray[$i][$j]
  1593. Next
  1594. Next
  1595. $aArray = $aTemp
  1596. Else ; optimimal method for a square grid
  1597. Local $vElement
  1598. For $i = 0 To $iDim_1 - 1
  1599. For $j = $i + 1 To $iDim_2 - 1
  1600. $vElement = $aArray[$i][$j]
  1601. $aArray[$i][$j] = $aArray[$j][$i]
  1602. $aArray[$j][$i] = $vElement
  1603. Next
  1604. Next
  1605. EndIf
  1606. Case Else
  1607. Return SetError(1, 0, 0)
  1608. EndSwitch
  1609. Return 1
  1610. EndFunc ;==>_ArrayTranspose
  1611. ; #FUNCTION# ====================================================================================================================
  1612. ; Author ........: Adam Moore (redndahead)
  1613. ; Modified.......: Ultima - code cleanup, optimization; Melba23 - added 2D support
  1614. ; ===============================================================================================================================
  1615. Func _ArrayTrim(ByRef $aArray, $iTrimNum, $iDirection = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0)
  1616. If $iDirection = Default Then $iDirection = 0
  1617. If $iStart = Default Then $iStart = 0
  1618. If $iEnd = Default Then $iEnd = 0
  1619. If $iSubItem = Default Then $iSubItem = 0
  1620. If Not IsArray($aArray) Then Return SetError(1, 0, 0)
  1621. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  1622. If $iEnd = 0 Then $iEnd = $iDim_1
  1623. If $iStart > $iEnd Then Return SetError(3, 0, -1)
  1624. If $iStart < 0 Or $iEnd < 0 Then Return SetError(3, 0, -1)
  1625. If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(3, 0, -1)
  1626. If $iStart > $iEnd Then Return SetError(4, 0, -1)
  1627. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1628. Case 1
  1629. If $iDirection Then
  1630. For $i = $iStart To $iEnd
  1631. $aArray[$i] = StringTrimRight($aArray[$i], $iTrimNum)
  1632. Next
  1633. Else
  1634. For $i = $iStart To $iEnd
  1635. $aArray[$i] = StringTrimLeft($aArray[$i], $iTrimNum)
  1636. Next
  1637. EndIf
  1638. Case 2
  1639. Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS) - 1
  1640. If $iSubItem < 0 Or $iSubItem > $iDim_2 Then Return SetError(5, 0, -1)
  1641. If $iDirection Then
  1642. For $i = $iStart To $iEnd
  1643. $aArray[$i][$iSubItem] = StringTrimRight($aArray[$i][$iSubItem], $iTrimNum)
  1644. Next
  1645. Else
  1646. For $i = $iStart To $iEnd
  1647. $aArray[$i][$iSubItem] = StringTrimLeft($aArray[$i][$iSubItem], $iTrimNum)
  1648. Next
  1649. EndIf
  1650. Case Else
  1651. Return SetError(2, 0, 0)
  1652. EndSwitch
  1653. Return 1
  1654. EndFunc ;==>_ArrayTrim
  1655. ; #FUNCTION# ====================================================================================================================
  1656. ; Author ........: SmOke_N
  1657. ; Modified.......: litlmike, Erik Pilsits, BrewManNH, Melba23
  1658. ; ===============================================================================================================================
  1659. Func _ArrayUnique(Const ByRef $aArray, $iColumn = 0, $iBase = 0, $iCase = 0, $iCount = $ARRAYUNIQUE_COUNT, $iIntType = $ARRAYUNIQUE_AUTO)
  1660. If $iColumn = Default Then $iColumn = 0
  1661. If $iBase = Default Then $iBase = 0
  1662. If $iCase = Default Then $iCase = 0
  1663. If $iCount = Default Then $iCount = $ARRAYUNIQUE_COUNT
  1664. ; Check array
  1665. If UBound($aArray, $UBOUND_ROWS) = 0 Then Return SetError(1, 0, 0)
  1666. Local $iDims = UBound($aArray, $UBOUND_DIMENSIONS), $iNumColumns = UBound($aArray, $UBOUND_COLUMNS)
  1667. If $iDims > 2 Then Return SetError(2, 0, 0)
  1668. ; Check parameters
  1669. If $iBase < 0 Or $iBase > 1 Or (Not IsInt($iBase)) Then Return SetError(3, 0, 0)
  1670. If $iCase < 0 Or $iCase > 1 Or (Not IsInt($iCase)) Then Return SetError(3, 0, 0)
  1671. If $iCount < 0 Or $iCount > 1 Or (Not IsInt($iCount)) Then Return SetError(4, 0, 0)
  1672. If $iIntType < 0 Or $iIntType > 4 Or (Not IsInt($iIntType)) Then Return SetError(5, 0, 0)
  1673. If $iColumn < 0 Or ($iNumColumns = 0 And $iColumn > 0) Or ($iNumColumns > 0 And $iColumn >= $iNumColumns) Then Return SetError(6, 0, 0)
  1674. ; Autocheck of first element
  1675. If $iIntType = $ARRAYUNIQUE_AUTO Then
  1676. Local $bInt, $sVarType
  1677. If $iDims = 1 Then
  1678. $bInt = IsInt($aArray[$iBase])
  1679. $sVarType = VarGetType($aArray[$iBase])
  1680. Else
  1681. $bInt = IsInt($aArray[$iBase][$iColumn])
  1682. $sVarType = VarGetType($aArray[$iBase][$iColumn])
  1683. EndIf
  1684. If $bInt And $sVarType = "Int64" Then
  1685. $iIntType = $ARRAYUNIQUE_FORCE64
  1686. Else
  1687. $iIntType = $ARRAYUNIQUE_FORCE32
  1688. EndIf
  1689. EndIf
  1690. ; Create error handler
  1691. ObjEvent("AutoIt.Error", __ArrayUnique_AutoErrFunc)
  1692. ; Create dictionary
  1693. Local $oDictionary = ObjCreate("Scripting.Dictionary")
  1694. ; Set case sensitivity
  1695. $oDictionary.CompareMode = Number(Not $iCase)
  1696. ; Add elements to dictionary
  1697. Local $vElem, $sType, $vKey, $bCOMError = False
  1698. For $i = $iBase To UBound($aArray) - 1
  1699. If $iDims = 1 Then
  1700. ; 1D array
  1701. $vElem = $aArray[$i]
  1702. Else
  1703. ; 2D array
  1704. $vElem = $aArray[$i][$iColumn]
  1705. EndIf
  1706. ; Determine method to use
  1707. Switch $iIntType
  1708. Case $ARRAYUNIQUE_FORCE32
  1709. ; Use element as key
  1710. $oDictionary.Item($vElem) ; Check if key exists - automatically created if not
  1711. If @error Then
  1712. $bCOMError = True ; Failed with an Int64, Ptr or Binary datatype
  1713. ExitLoop
  1714. EndIf
  1715. Case $ARRAYUNIQUE_FORCE64
  1716. $sType = VarGetType($vElem)
  1717. If $sType = "Int32" Then
  1718. $bCOMError = True ; Failed with an Int32 datatype
  1719. ExitLoop
  1720. EndIf ; Create key
  1721. $vKey = "#" & $sType & "#" & String($vElem)
  1722. If Not $oDictionary.Item($vKey) Then ; Check if key exists
  1723. $oDictionary($vKey) = $vElem ; Store actual value in dictionary
  1724. EndIf
  1725. Case $ARRAYUNIQUE_MATCH
  1726. $sType = VarGetType($vElem)
  1727. If StringLeft($sType, 3) = "Int" Then
  1728. $vKey = "#Int#" & String($vElem)
  1729. Else
  1730. $vKey = "#" & $sType & "#" & String($vElem)
  1731. EndIf
  1732. If Not $oDictionary.Item($vKey) Then ; Check if key exists
  1733. $oDictionary($vKey) = $vElem ; Store actual value in dictionary
  1734. EndIf
  1735. Case $ARRAYUNIQUE_DISTINCT
  1736. $vKey = "#" & VarGetType($vElem) & "#" & String($vElem)
  1737. If Not $oDictionary.Item($vKey) Then ; Check if key exists
  1738. $oDictionary($vKey) = $vElem ; Store actual value in dictionary
  1739. EndIf
  1740. EndSwitch
  1741. Next
  1742. ; Create return array
  1743. Local $aValues, $j = 0
  1744. If $bCOMError Then ; Mismatch Int32/64
  1745. Return SetError(7, 0, 0)
  1746. ElseIf $iIntType <> $ARRAYUNIQUE_FORCE32 Then
  1747. ; Extract values associated with the unique keys
  1748. Local $aValues[$oDictionary.Count]
  1749. For $vKey In $oDictionary.Keys()
  1750. $aValues[$j] = $oDictionary($vKey)
  1751. ; Check for Ptr datatype
  1752. If StringLeft($vKey, 5) = "#Ptr#" Then
  1753. $aValues[$j] = Ptr($aValues[$j])
  1754. EndIf
  1755. $j += 1
  1756. Next
  1757. Else
  1758. ; Only need to list the unique keys
  1759. $aValues = $oDictionary.Keys()
  1760. EndIf
  1761. ; Add count if required
  1762. If $iCount Then
  1763. _ArrayInsert($aValues, 0, $oDictionary.Count)
  1764. EndIf
  1765. ; Return array
  1766. Return $aValues
  1767. EndFunc ;==>_ArrayUnique
  1768. ; #FUNCTION# ====================================================================================================================
  1769. ; Author ........: jchd, jpm
  1770. ; Modified.......:
  1771. ; ===============================================================================================================================
  1772. Func _Array1DToHistogram($aArray, $iSizing = 100)
  1773. If UBound($aArray, 0) > 1 Then Return SetError(1, 0, "")
  1774. $iSizing = $iSizing * 8
  1775. Local $t, $n, $iMin = 0, $iMax = 0, $iOffset = 0
  1776. For $i = 0 To UBound($aArray) - 1
  1777. $t = $aArray[$i]
  1778. $t = IsNumber($t) ? Round($t) : 0
  1779. If $t < $iMin Then $iMin = $t
  1780. If $t > $iMax Then $iMax = $t
  1781. Next
  1782. Local $iRange = Int(Round(($iMax - $iMin) / 8)) * 8
  1783. Local $iSpaceRatio = 4
  1784. For $i = 0 To UBound($aArray) - 1
  1785. $t = $aArray[$i]
  1786. If $t Then
  1787. $n = Abs(Round(($iSizing * $t) / $iRange) / 8)
  1788. $aArray[$i] = ""
  1789. If $t > 0 Then
  1790. If $iMin Then
  1791. $iOffset = Int(Abs(Round(($iSizing * $iMin) / $iRange) / 8) / 8 * $iSpaceRatio)
  1792. $aArray[$i] = __Array_StringRepeat(ChrW(0x20), $iOffset)
  1793. EndIf
  1794. Else
  1795. If $iMin <> $t Then
  1796. $iOffset = Int(Abs(Round(($iSizing * ($t - $iMin)) / $iRange) / 8) / 8 * $iSpaceRatio)
  1797. $aArray[$i] = __Array_StringRepeat(ChrW(0x20), $iOffset)
  1798. EndIf
  1799. EndIf
  1800. $aArray[$i] &= __Array_StringRepeat(ChrW(0x2588), Int($n / 8))
  1801. $n = Mod($n, 8)
  1802. If $n > 0 Then $aArray[$i] &= ChrW(0x2588 + 8 - $n)
  1803. $aArray[$i] &= ' ' & $t
  1804. Else
  1805. $aArray[$i] = ""
  1806. EndIf
  1807. Next
  1808. Return $aArray
  1809. EndFunc ;==>_Array1DToHistogram
  1810. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1811. ; Name...........: __Array_StringRepeat
  1812. ; Description ...: Repeats a string a specified number of times
  1813. ; Syntax.........: __Array_StringRepeat ( $sString, $iRepeatCount )
  1814. ; Parameters ....: $sString - String to repeat
  1815. ; $iRepeatCount - Number of times to repeat the string
  1816. ; Return values .: a string with specified number of repeats.
  1817. ; Author ........: Jeremy Landes <jlandes at landeserve dot com>
  1818. ; Modified.......: jpm
  1819. ; Remarks .......: This function is used internally. similar to _StringRepeat() but if $iRepeatCount = 0 returns ""
  1820. ; Related .......:
  1821. ; Link ..........:
  1822. ; Example .......:
  1823. ; ===============================================================================================================================
  1824. Func __Array_StringRepeat($sString, $iRepeatCount)
  1825. ; Casting Int() takes care of String/Int, Numbers.
  1826. $iRepeatCount = Int($iRepeatCount)
  1827. ; Zero is a valid repeat integer.
  1828. If StringLen($sString) < 1 Or $iRepeatCount <= 0 Then Return SetError(1, 0, "")
  1829. Local $sResult = ""
  1830. While $iRepeatCount > 1
  1831. If BitAND($iRepeatCount, 1) Then $sResult &= $sString
  1832. $sString &= $sString
  1833. $iRepeatCount = BitShift($iRepeatCount, 1)
  1834. WEnd
  1835. Return $sString & $sResult
  1836. EndFunc ;==>__Array_StringRepeat
  1837. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1838. ; Name...........: __Array_ExeterInternal
  1839. ; Description ...: Permute Function based on an algorithm from Exeter University.
  1840. ; Syntax.........: __Array_ExeterInternal ( ByRef $aArray, $iStart, $iSize, $sDelimiter, ByRef $aIdx, ByRef $aResult )
  1841. ; Parameters ....: $aArray - The Array to get Permutations
  1842. ; $iStart - Starting Point for Loop
  1843. ; $iSize - End Point for Loop
  1844. ; $sDelimiter - String result separator
  1845. ; $aIdx - Array Used in Rotations
  1846. ; $aResult - Resulting Array
  1847. ; Return values .: Success - Computer name
  1848. ; Author ........: Erik Pilsits
  1849. ; Modified.......: 07/08/2008
  1850. ; Remarks .......: This function is used internally. Permute Function based on an algorithm from Exeter University.
  1851. ; +
  1852. ; http://www.bearcave.com/random_hacks/permute.html
  1853. ; Related .......:
  1854. ; Link ..........:
  1855. ; Example .......:
  1856. ; ===============================================================================================================================
  1857. Func __Array_ExeterInternal(ByRef $aArray, $iStart, $iSize, $sDelimiter, ByRef $aIdx, ByRef $aResult, ByRef $iCount)
  1858. If $iStart == $iSize - 1 Then
  1859. For $i = 0 To $iSize - 1
  1860. $aResult[$iCount] &= $aArray[$aIdx[$i]] & $sDelimiter
  1861. Next
  1862. If $sDelimiter <> "" Then $aResult[$iCount] = StringTrimRight($aResult[$iCount], StringLen($sDelimiter))
  1863. $iCount += 1
  1864. Else
  1865. Local $iTemp
  1866. For $i = $iStart To $iSize - 1
  1867. $iTemp = $aIdx[$i]
  1868. $aIdx[$i] = $aIdx[$iStart]
  1869. $aIdx[$iStart] = $iTemp
  1870. __Array_ExeterInternal($aArray, $iStart + 1, $iSize, $sDelimiter, $aIdx, $aResult, $iCount)
  1871. $aIdx[$iStart] = $aIdx[$i]
  1872. $aIdx[$i] = $iTemp
  1873. Next
  1874. EndIf
  1875. EndFunc ;==>__Array_ExeterInternal
  1876. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1877. ; Name...........: __Array_Combinations
  1878. ; Description ...: Creates Combination
  1879. ; Syntax.........: __Array_Combinations ( $iN, $iR )
  1880. ; Parameters ....: $iN - Value passed on from UBound($aArray)
  1881. ; $iR - Size of the combinations set
  1882. ; Return values .: Integer value of the number of combinations
  1883. ; Author ........: Erik Pilsits
  1884. ; Modified.......: 07/08/2008
  1885. ; Remarks .......: This function is used internally. PBased on an algorithm by Kenneth H. Rosen.
  1886. ; +
  1887. ; http://www.bearcave.com/random_hacks/permute.html
  1888. ; Related .......:
  1889. ; Link ..........:
  1890. ; Example .......:
  1891. ; ===============================================================================================================================
  1892. Func __Array_Combinations($iN, $iR)
  1893. Local $i_Total = 1
  1894. For $i = $iR To 1 Step -1
  1895. $i_Total *= ($iN / $i)
  1896. $iN -= 1
  1897. Next
  1898. Return Round($i_Total)
  1899. EndFunc ;==>__Array_Combinations
  1900. ; #INTERNAL_USE_ONLY# ===========================================================================================================
  1901. ; Name...........: __Array_GetNext
  1902. ; Description ...: Creates Combination
  1903. ; Syntax.........: __Array_GetNext ( $iN, $iR, ByRef $iLeft, $iTotal, ByRef $aIdx )
  1904. ; Parameters ....: $iN - Value passed on from UBound($aArray)
  1905. ; $iR - Size of the combinations set
  1906. ; $iLeft - Remaining number of combinations
  1907. ; $iTotal - Total number of combinations
  1908. ; $aIdx - Array containing combinations
  1909. ; Return values .: Function only changes values ByRef
  1910. ; Author ........: Erik Pilsits
  1911. ; Modified.......: 07/08/2008
  1912. ; Remarks .......: This function is used internally. PBased on an algorithm by Kenneth H. Rosen.
  1913. ; +
  1914. ; http://www.bearcave.com/random_hacks/permute.html
  1915. ; Related .......:
  1916. ; Link ..........:
  1917. ; Example .......:
  1918. ; ===============================================================================================================================
  1919. Func __Array_GetNext($iN, $iR, ByRef $iLeft, $iTotal, ByRef $aIdx)
  1920. If $iLeft == $iTotal Then
  1921. $iLeft -= 1
  1922. Return
  1923. EndIf
  1924. Local $i = $iR - 1
  1925. While $aIdx[$i] == $iN - $iR + $i
  1926. $i -= 1
  1927. WEnd
  1928. $aIdx[$i] += 1
  1929. For $j = $i + 1 To $iR - 1
  1930. $aIdx[$j] = $aIdx[$i] + $j - $i
  1931. Next
  1932. $iLeft -= 1
  1933. EndFunc ;==>__Array_GetNext
  1934. 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.
  1935. If $iCompNumeric = Default Then $iCompNumeric = 0
  1936. If $iCompNumeric <> 1 Then $iCompNumeric = 0
  1937. If $iStart = Default Then $iStart = 0
  1938. If $iEnd = Default Then $iEnd = 0
  1939. If $iSubItem = Default Then $iSubItem = 0
  1940. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
  1941. Local $iDim_1 = UBound($aArray, $UBOUND_ROWS) - 1
  1942. If $iDim_1 < 0 Then Return SetError(1, 0, -1)
  1943. If $iEnd = -1 Then $iEnd = $iDim_1
  1944. If $iStart = -1 Then $iStart = 0
  1945. If $iStart < -1 Or $iEnd < -1 Then Return SetError(3, 0, -1)
  1946. If $iStart > $iDim_1 Or $iEnd > $iDim_1 Then Return SetError(3, 0, -1)
  1947. If $iStart > $iEnd Then Return SetError(4, 0, -1)
  1948. If $iDim_1 < 0 Then Return SetError(5, 0, -1)
  1949. Local $iMaxMinIndex = $iStart
  1950. Switch UBound($aArray, $UBOUND_DIMENSIONS)
  1951. Case 1
  1952. If $iCompNumeric Then
  1953. For $i = $iStart To $iEnd
  1954. If $fuComparison(Number($aArray[$i]), Number($aArray[$iMaxMinIndex])) Then $iMaxMinIndex = $i
  1955. Next
  1956. Else
  1957. For $i = $iStart To $iEnd
  1958. If $fuComparison($aArray[$i], $aArray[$iMaxMinIndex]) Then $iMaxMinIndex = $i
  1959. Next
  1960. EndIf
  1961. Case 2
  1962. If $iSubItem < 0 Or $iSubItem > UBound($aArray, $UBOUND_COLUMNS) - 1 Then Return SetError(6, 0, -1)
  1963. If $iCompNumeric Then
  1964. For $i = $iStart To $iEnd
  1965. If $fuComparison(Number($aArray[$i][$iSubItem]), Number($aArray[$iMaxMinIndex][$iSubItem])) Then $iMaxMinIndex = $i
  1966. Next
  1967. Else
  1968. For $i = $iStart To $iEnd
  1969. If $fuComparison($aArray[$i][$iSubItem], $aArray[$iMaxMinIndex][$iSubItem]) Then $iMaxMinIndex = $i
  1970. Next
  1971. EndIf
  1972. Case Else
  1973. Return SetError(2, 0, -1)
  1974. EndSwitch
  1975. Return $iMaxMinIndex
  1976. EndFunc ;==>__Array_MinMaxIndex
  1977. Func __Array_GreaterThan($vValue1, $vValue2)
  1978. Return $vValue1 > $vValue2
  1979. EndFunc ;==>__Array_GreaterThan
  1980. Func __Array_LessThan($vValue1, $vValue2)
  1981. Return $vValue1 < $vValue2
  1982. EndFunc ;==>__Array_LessThan
  1983. Func __ArrayUnique_AutoErrFunc()
  1984. ; Do nothing special, just check @error after suspect functions.
  1985. EndFunc ;==>__ArrayUnique_AutoErrFunc