Search the Community

Showing results for tags 'array'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General
    • Announcements and Site News
    • Chat
    • Administration
  • AutoIt v3
    • AutoIt Help and Support
    • AutoIt Technical Discussion
    • AutoIt Example Scripts
  • Scripting and Development
    • Developer General Discussion
    • Language Specific Discussion
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Categories

  • AutoIt Team
    • Beta
    • MVP
  • AutoIt
    • Automation
    • Databases and web connections
    • Data compression
    • Encryption and hash
    • Games
    • GUI Additions
    • Hardware
    • Information gathering
    • Internet protocol suite
    • Maths
    • Media
    • PDF
    • Security
    • Social Media and other Website API
    • Windows
  • Scripting and Development
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Categories

  • Forum
  • AutoIt

Calendars

  • Community Calendar

Found 232 results

  1. Haven't had much time to code recently. However the following thread inspired me. The debate about linear, parallel and binary search methods was rather interesting and, in an attempt to be diplomatic, I decided to combine @jchd's suggestion with @LarsJ's binary search example. I decided that the binary search algorithm required modification to make it more linear. As usual, 'if you invent something, it probably already exists and if it already exists, it exists for a reason'. My first attempt was not all that good. The code worked but was really a mess. I blame peer pressure (to post an example of a parallel search method). I will delete that old code in due course. With a little memory jogging and a glance at the help file, the solution turned out to be quite easy: I just needed a better understanding of Euler. Further modification will be needed to work with more complicated unicode strings. The output could be returned as an array or a delimitered string. I'm not so interested in those details. I'm just going to post the algorithm for now and anyone, who wants to, can modify it to suit their needs. Both arrays must contain at least 1 element. Local $aFoo = [0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,19,20,23,24,26,30,35,39,40,41] Local $aBar = [0,1,5,6,7,8,9,10,11,12,13,14,17,18,19,21,24,25,26,27,34,35,38,40] ParallelExponetialSearch($aFoo, $aBar) ; Compares two lists - returning positive matches. Each input array must be unique (individually) and in alphabetical order. Func ParallelExponetialSearch($aFoo, $aBar) Local $sFind, _ $iMin_F = -1, $iMax_F = UBound($aFoo) -1, $Lo_F = $iMin_F, $Hi_F, _ $iMin_B = -1, $iMax_B = UBound($aBar) -1, $Lo_B = $iMin_B, $Hi_B While $iMin_F < $iMax_F And $iMin_B < $iMax_B ; Toggle Arrays - Which array has most untested elements? This is the one we want to search next, ; so we can bypass more comparisons because (in theory) mismatches have a greater chance of being skipped. If $iMax_F - $iMin_F >= $iMax_B - $iMin_B Then ; $aFoo has more (or an equal number of) untested elements $Hi_F = $iMax_F $iMin_B += 1 $sFind = $aBar[$iMin_B] While $Lo_F < $Hi_F ; search $aFoo For $i = 0 To Floor(Log($Hi_F - $Lo_F) / Log(2)) $Lo_F = $iMin_F + 2^$i If $aFoo[$Lo_F] = $sFind Then $iMin_F = $Lo_F ; each match should be added to the output [perhaps an array] ConsoleWrite($sFind & " found at $aFoo[" & $Lo_F & "] = $aBar[" & $iMin_B & "]" & @LF) ExitLoop 2 ElseIf $aFoo[$Lo_F] > $sFind Then $Hi_F = $Lo_F -1 $iMin_F += Floor(2^($i -1)) $Lo_F = $iMin_F ContinueLoop 2 EndIf Next $iMin_F = $Lo_F ; minimum increment is one WEnd Else ; $aBar has more untested elements $Hi_B = $iMax_B $iMin_F += 1 $sFind = $aFoo[$iMin_F] While $Lo_B < $Hi_B ; search $aBar For $i = 0 To Floor(Log($Hi_B - $Lo_B) / Log(2)) $Lo_B = $iMin_B + 2^$i If $aBar[$Lo_B] = $sFind Then $iMin_B = $Lo_B ; each match should be added to the output [perhaps an array] ConsoleWrite($sFind & " found at $aFoo[" & $iMin_F & "] = $aBar[" & $Lo_B & "]" & @LF) ExitLoop 2 ElseIf $aBar[$Lo_B] > $sFind Then $Hi_B = $Lo_B -1 $iMin_B += Floor(2^($i -1)) $Lo_B = $iMin_B ContinueLoop 2 EndIf Next $iMin_B = $Lo_B ; minimum increment is one WEnd EndIf WEnd EndFunc ;==> ParallelExponetialSearch I hope this will be useful to someone. I believe it deserved a thread of its own!
  2. Afternoon! I have a requirement to return both a string and an array from a function so as a result I put them both into an array and returned that. I can access them in their entirety after returning them but then I can't seem to access the array elements after this. Should I be able to or is there a prettier way? #include <Array.au3> ;Memory info returned as a string and an array $memoryInfo = _getMemoryInfo() msgbox(0,"Memory Info",$memoryInfo[0]) _ArrayDisplay($memoryInfo[1],"Memory as an Array") Local $newArray[7] $memoryInfo[1] = $newArray msgbox(0,"Test element",$newArray[0]) _ArrayDisplay($newArray) Func _getMemoryInfo() Local $newArray[7] Local $array = MemGetStats() $newArray[0] = $array[0] ;% of memory in use $newArray[1] = Round($array[1]/1024 * 0.001,2) ;Total physical RAM $newArray[2] = Round($array[2]/1024 * 0.001,2) ;Availaible physical RAM $newArray[3] = Round($array[3]/1024 * 0.001,2) ;Total pagefile $newArray[4] = Round($array[4]/1024 * 0.001,2) ;Available pagefile $newArray[5] = Round($array[5]/1024 * 0.001,2) ;Total virtual $newArray[6] = Round($array[6]/1024 * 0.001,2) ;Available virtual $memoryUsage = $newArray[1] - $newarray[2] $pagefileUsage = $newArray[3] - $newarray[4] ;Output/Return Local $returnArray[2] $returnArray[0] = "Memory: " & $memoryUsage & " GB/" & $newArray[1] & " GB " & @CRLF & "Pagefile: " & $pagefileUsage & " GB/" & $newArray[3] & " GB " $returnArray[1] = $newArray return $returnArray EndFunc A bit messy but hopefully it's understandable what I'm trying to achieve. Thanks!
  3. I write this script to compare to array, well Do you have a better way to do it? #include <Constants.au3> #include <Array.au3> #include <File.au3> #include <MsgBoxConstants.au3> $a = FileSelectFolder("seleziona cartella A",@ScriptDir) $fold_A = _FileListToArrayRec($a,"*",2,1,0,1) $b = FileSelectFolder("seleziona cartella B",@ScriptDir) $fold_B = _FileListToArrayRec($b,"*",2,1,0,1) $tota = UBound($fold_A)-1 $totb = UBound($fold_B)-1 If $tota > $totb Then findx($fold_A,$fold_B) Else findx($fold_B,$fold_A) EndIf Func findx($min,$max) For $i = 0 To UBound($min)-1 $found = _ArraySearch($max, $min[$i]) If $found = -1 Then ConsoleWrite($min[$i]&@CRLF) EndIf Next EndFunc
  4. I am working on a Video Player Test Script. I am reading a text file into a 3d array to be displayed in a GUI. Array Content: [x][0]FileName.mp4 [x][1]UsageCount -> Up to a 4 digit number [x][2]EnableUsageCount (True/False) In the GUI the user can check the filename box, edit the number of usages and check EnableUsageCount to turn on the UsageCount control using the UsageCount number for the maximum number of plays. To make this easier to deal with I have removed the EnableUsageCount section, and am just concentrating on getting a method to put the edited (or unchanged) UsageCount in the array. Currently nothing is read into the array, due to my using the wrong method in the Case statement. Here are code snippets of what I am trying to do: ; Snippets from script ; I read the text file at the bottom and put the .mp4 filenames in $aManifest[x][0] and UsageCount in $aManifest[x][1] ; Then I create a GUI to display the .mp4 filenames with checkboxes and the UsageCount to the right. UsageCount is editable by the user. ; If the filename is checked, I want to read the filename into $aCheckedVideos[x][0] and the updated UsageCount in $aCheckedVideos[x][1] ; The GUICtrlRead($aVideoName[$i]) with Case $GUI_CHECKED & UNCHECKED works for the checkboxes ; This section puts the filenames in the GUI with a checkbox For $i = 0 to $iMMCount Step 1 $sMP4Text = $aManifest[$i][0] $iMP4Length = StringLen($sMP4Text) $aVideoName[$i] = GUICtrlCreateCheckbox($sMP4Text,$iLeft, $iTop) $iTop += 30 Next ; This section reads numbers from the Manifest array, and I want to be able to change the number and have them saved. ; So the Case $GUI_CHECKED & UNCHECKED won't work here, and I can't figure out what I should be doing here. For $i = 0 to $iMMCount Step 1 $sUsageText = $aManifest[$i][1] $aUsageCount[$i] = GUICtrlCreateInput($sUsageText,$iLeft, $iTop, 50,18, $GUI_DOCKAUTO) GUICtrlSetPos($aUsageCount[$i],200) $iTop += 30 Next While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $idCloseGUI For $i = 0 To $iMMNewCount Step 1 Switch GUICtrlRead($aVideoName[$i]) Case $GUI_CHECKED $aCheckedVideos[$i][0] = $aManifest[$i][0] ; If checked, I put the results into a two D array Case $GUI_UNCHECKED ; where Video Name is $aCheckedVideos[x][0] EndSwitch Switch GUICtrlRead($aUsageCounter[$i]) Case $GUI_CHECKED $aCheckedVideos[$i][1] = $aUsageCount[$i] ;I want to put the text (numbers) in $aCheckedVideos[x][1] Case $GUI_UNCHECKED ;but what is returned is blank, probably due to EndSwitch ; $GUI_CHECKED being the wrong thing. Next ExitLoop EndSwitch WEnd ;The txt file I'm reading has the following: ;~ /** Title #1: Big Buck Bunny 1080p **/ ;~ "Name": "Big Buck Bunny", ;~ "URI": "..\\MediaFiles\\bbb_1080_60s.mp4", ;~ "UsageCount": 9999, ;~ "URI": "..\\MediaFiles\\bbb_1080_60s_enc1.mp4", ;~ "UsageCount": 45, ;~ "URI": "..\\MediaFiles\\bbb_1080_60s_enc1.mp4", ;~ "UsageCount": 2, ;~ /** Title #2: Tears of Steel 4K **/ ;~ "Name": "Tears of Steel 4K", ;~ "URI": "..\\MediaFiles\\tos_4K_60s_HEVC.mp4", ;~ "UsageCount": 9876, ;~ "URI": "..\\MediaFiles\\tos_4K_60s_HEVC_enc2.mp4", ;~ "UsageCount": 0, ;~ "URI": "..\\MediaFiles\\tos_4K_60s_HEVC_enc2.mp4", ;~ "UsageCount": 5, I am certain that the section Switch GUICtrlRead($aUsageCounter[$i]) Case $GUI_CHECKED $aCheckedVideos[$i][1] = $aUsageCount[$i] ;I want to put the text (numbers) in $aCheckedVideos[x][1] Case $GUI_UNCHECKED ;but what is returned is blank, probably due to EndSwitch ; $GUI_CHECKED being the wrong thing. is wrong, and this is what I am looking for help with. Instead of $GUI_CHECKED what should I be looking for? The worst part of this is I had this working late last night, and then lost my changes and cannot for the life of me remember how I had this working. Help is truly appreciated! Jibberish
  5. I am having difficulties getting updated results from GUICtrlCreateInput. I wrote a small script to demonstrate what I am trying to do. This script reads a text file into an array and displays the Name and Number from the text file. The user can check a name and change the number, and the results are displayed in _ArrayDisplay. Only the Checked names are displayed in their original position. This is necessary for future plumbing. The problem with this script is the original number is returned, not the changed number. I cannot figure out how to get the updated number to be displayed. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; This script reads a text file into an array and displays the Name and Number from the text file. ; The user can check a name and change the number, and the results are displayed in _ArrayDisplay. ; Only the Checked names are displayed in their original position. This is necessary for future ; plumbing. ; ; The problem with this script is the original number is returned, not the changed number. I cannot ; figure out how to get the updated number to be displayed. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include-once #include <MsgBoxConstants.au3> #include <array.au3> #include <Date.au3> #include <WinAPIFiles.au3> #include <AutoItConstants.au3> #include <Misc.au3> #include <File.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> Local $iMax = 6 ;Default number of Videos - 1 for the array counter Dim $aTextFile[$iMax][2] ; [start with 5 entries][Name, Number] Don't get confused! [Row][Column] Local $i = 0 Local $iLeft = 30 Local $iTop = 30 Local $sName Local $sNumber Local $aArray Local $iMaxCol = 5 Local $iRow = 0 Local $iCol = 0 Local $aNumberCount[$iMaxCol][2] $aArray1 = ReadFile() $aNamesNumbers = DisplayNames($aArray1) _ArrayDisplay($aNamesNumbers) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; ReadFile() places the contents of the NameNumber.txt file in an array ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func ReadFile() Local $sFileData = @ScriptDir & "\NameNumber.txt" Local $iStrReturn = 0 Local $aArrayFile Local $aTextFile[$iMaxCol][2] Local $aName Local $sCheckBox1 Const $iL = 10 ; Count from Left for GUI so all buttons line up Local $sFill Local $iA = 0, $iN = 0 ; Put the Names into an Array _FileReadToArray($sFileData, $aArrayFile) For $iA = 0 To $aArrayFile[0] ; Step through the array looking for Names If StringInStr($aArrayFile[$iA], "Name:") Then $aName = StringSplit($aArrayFile[$iA],":") $sFill = $aName[2] If UBound($aTextFile) <= $iRow Then ; Resize the array when $iRow is equal to the element count in the array to prevent subscript error ReDim $aTextFile[UBound($aTextFile) + 1][$iMaxCol] EndIf $aTextFile[$iRow][$iCol] = $sFill $iRow += 1 EndIf Next $iCol = 1 $iRow = 0 $sFill = "" For $iA = 1 To $aArrayFile[0] ; Step through the array looking for Numbers If StringInStr($aArrayFile[$iA], "Number:") Then $aName = StringSplit($aArrayFile[$iA],":") $sFill = $aName[2] If UBound($aTextFile) <= $iRow Then ; Resize the array when $iRow is equal to the element count in the array to prevent subscript error ReDim $aTextFile[UBound($aTextFile) + 1][$iMaxCol] EndIf $aTextFile[$iRow][$iCol] = $sFill $iRow += 1 EndIf Next Return $aTextFile EndFunc ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display the Name and Number ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func DisplayNames($aArray1) Local $aName[$iMax] Local $aNumbers[$iMax] $iMMCount = UBound($aArray1) $iMMCount -=1 Local $iWidth = 300 Local $iLength = 300;$iMMCount * 30 GUISetFont(12) $hGUI = GUICreate("Edit / Update Number Test", $iWidth, $iLength, -1, -1) GUICtrlCreateLabel(" Name Number",1,5) ;$iTop += 30 ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display Name with a Checkbox. Only Checked Names should be saved. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For $i = 0 to $iMMCount Step 1 $sNameText = $aArray1[$i][0] $iNameLength = StringLen($sNameText) $aName[$i] = GUICtrlCreateCheckbox($sNameText,$iLeft, $iTop) $iTop += 30 Next ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display the number from the text file below each name. Allow the user to change the number and display the ; new number. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $iLeft = 60 GUIStartGroup() $iTop = 28 For $i = 0 to $iMMCount Step 1 $sNumberText = $aArray1[$i][1] $aNumberCount[$i][1] = $sNumberText $aNumberCount[$i][0] = GUICtrlCreateInput($sNumberText,$iLeft, $iTop, 50,18, $GUI_DOCKAUTO) GUICtrlSetPos($aNumberCount[$i][0],200) $iTop += 30 Next ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Read the checked names and (possibly updated) number ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $iMMCount = UBound($aNumberCount) $iMMNewCount = $iMMCount - 1 Local $aGUICheckbox[$iMMCount] Local $aCheckedNameNumber[$iMMCount][2] $iLeft = 30 Local $idCloseGUI = GUICtrlCreateButton("Close",$iLeft, $iTop) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $idCloseGUI For $i = 0 To $iMMNewCount Step 1 Switch GUICtrlRead($aName[$i]) Case $GUI_CHECKED $aCheckedNameNumber[$i][0] = $aArray1[$i][0] Case $GUI_UNCHECKED EndSwitch Switch GUICtrlRead($aNumberCount[$i][0]) Case $aCheckedNameNumber[$i][1] = GUICtrlRead($aNumberCount[$i][1]) EndSwitch Next ExitLoop EndSwitch WEnd For $i = 0 to $iMMNewCount step 1 GUICtrlRead($aNumberCount[$i][0]) If $aCheckedNameNumber[$i][0] <> "" Then $aCheckedNameNumber[$i][1] = $aNumberCount[$i][1] EndIf Next GUIDelete($hGUI) Return $aCheckedNameNumber EndFunc This is the text file I am reading. If you want to try this out put the NameNumber.txt file in your script directory. It's attached to the post. * This is a dummy file with a Name and Number * The only purpose of this file is to read the updated Number. Name:Taggart Number:916 Name:Mongo Number:90 Name:Hedley Lamarr Number:22 Name:Bart Number:9999 Name:The Waco Kid Number:2244 If I change the number, the original number is displayed at the end, not the updated/modified number. I need the modified number to be displayed. Thanks in advance for any assistance! Jibberish NameNumber.txt
  6. Hello everybody, so I might found a bug in _ArraySearch: #include <Array.au3> Local $abc[2] = ["b", "b"] $h = "+---------------------------------+" & @CRLF ConsoleWrite($h) For $i = 0 To 1 $abc[0] = 0 out() $abc[0] = 1 out() $abc[0] = -1 out() $abc[0] = "Abc" out() $abc[1] = "Hello" Next Func txt() Return "$abc = [" & $abc[0] & ", " & $abc[1] & "]" & @CRLF & _ "> _ArraySearch($abc,""Hello"") = " EndFunc ;==>txt Func shouldoutput($ans) Return "_ArraySearch Should return: " & ($ans ? 1 : -1) EndFunc ;==>shouldoutput Func out() ConsoleWrite("> " & txt() & _ArraySearch($abc, "Hello") & @CRLF & "> " & shouldoutput($abc[1] == "Hello") & @CRLF & $h) EndFunc ;==>out Exit Sorry for this messy script
  7. _ArrayDisplay($aArray, "Window Title", "1:", 0, Default, "Column") ; Expected results are rows 1 to the end of the array, all columns. The result is rows 0-1, all columns. The API reference is here: https://www.autoitscript.com/autoit3/docs/libfunctions/_ArrayDisplay.htm Am I doing something wrong?
  8. I am trying to add data to an array and I keep getting the error "Subscript used on non-accessible variable ". #include <array.au3> ; Includes, etc ~ ~ ~ Local $aOptionsArray[3] $aOptionsArray = CheckboxesAndRadioButtons() _ArrayDisplay($aOptionsArray) Func CheckboxesAndRadioButtons() ; Create Checkboxes and Radio Buttons and read the results ~ ~ ~ ; Radio Buttons to Array ; $aOptions[0] = $bTestSelectForever ; $aOptions[1] = $bTestSelect3Times ; $aOptions[2] = $bTestSelectOnce If $bSelect1 = 1 Then $aOptions[0] = "True" Else $aOptions[0] = "False" <<< This is where the error occurs. EndIf If $bSelect2 = 1 Then $aOptions[1] = "True" Else $aOptions[1] = "False" EndIf If $bSelect3 = 1 Then $aOptions[2] = "True" Else $aOptions[2] = "False" EndIf Return $aOptions EndFunc Is putting data into an array while in a If - Then - Else illegal?
  9. Hi all, First, I want to give a huge shout-out to the community. I'm completely self-taught, and have never had to actually ask a question before because the forum is that good at answering questions and explaining things. However, I'm kind of stumped here, and I've been stuck on this problem for almost a full day. I'm working on a script to populate drafts of deeds at work. I have the main GUI and a function (ctrl($n) and read()) for adding fields to find and data to replace it with to an array for later use with _word_docfindreplace. All of that works. However, due to the way I have the forms set up, I need to create additional fields and info based on the data that's there. Specifically, if there's only one buyer, I need to add the field [Buyer1&2] and the data in $aArray_Base for [Buyer 1]. I also need to add a field [Buyer 2] and have a blank data set in the next column over in the array, and I need to do the same for the Seller. To this end, the function parties() sets boolean variables $2buyers and $2sellers accordingly. Then, I have buyers() and sellers() to populate the data. The problem that I'm running into is that each function works... when ONLY the buyer 1 name field is filled, and when ONLY the seller 1 field is filled. So if I fill Buyer 1 Name and save it, the data is populated correctly. But when I fill Buyer 1 and Seller 1 name, only the buyer 1 data populates correctly. Worse, when I fill several fields, neither populate correctly. I have no idea why this happens. I've added messageboxes to debug throughout the entire process and can't pinpoint what's causing the issue. The entire script is below. The function(s) in question are buyers() and sellers(). Only Sellers() has messageboxes throughout. Can someone help walk me through what might be causing this and help me find a solution? Thanks a ton in advance, and sorry for the wall of text. -Anoig
  10. Cleaning up some old folders and found this little snippit. Think I was using this back when I was trying to create 2d maps for a game I was making in GDI+ (that never got finished). Pretty straight forward, searches an array for an array. #include <Array.Au3> Search() Func Search() Local $aArrayToFind[][] = [["V", "V", "V", "V", "V"], ["V", "V", "V", "V", "V"], ["V", "V", "V", "V", "B"], ["V", "V", "V", "V", "B"], ["V", "V", "V", "V", "B"]] Local $aArrayToSearch[][] = [["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "X", "B", "B", "B", "B", "B", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "V", "V", "V", "X", "V", "V", "B", "D", "B", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "X", "B", "D", "B", "B", "B", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "V", "V", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "V", "X", "V", "V", "X", "B", "B", "B", "B", "B", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "V", "V", "V", "V", "V", "M", "M", "M", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "B", "D", "B", "B", "B", "V", "V", "V", "V", "V", "M", "M", "M", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "M", "M", "D", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "V", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "C", "C", "D", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "L", "L", "L", "L", "W", "W", "W", "W", "W", "W", "L", "L", "L", "V", "V", "V", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"]] Local $aArrayInArray = ArrayInArray($aArrayToSearch, $aArrayToFind) If (@Error) Then MsgBox("", "Error", "Error doing search: " & @Error) Else If ($aArrayInArray[0] = 1) Then ToolTip("Start Coords = " & $aArrayInArray[1] & ", " & $aArrayInArray[2] & @LF & _ "End Coords = " & $aArrayInArray[1] + UBound($aArrayToFind, $UBOUND_ROWS) - 1 & ", " & $aArrayInArray[2] + UBound($aArrayToFind, $UBOUND_COLUMNS) - 1 & @LF & _ "(Approx) Center coords = " & $aArrayInArray[1] + Int(UBound($aArrayToFind, $UBOUND_ROWS) / 2) & ", " & $aArrayInArray[2] + Int(UBound($aArrayToFind, $UBOUND_COLUMNS) / 2), 0, 0) $aArrayToSearch[$aArrayInArray[1]][$aArrayInArray[2]] = "Start" $aArrayToSearch[$aArrayInArray[1] + UBound($aArrayToFind, $UBOUND_ROWS) - 1][$aArrayInArray[2] + UBound($aArrayToFind, $UBOUND_COLUMNS) - 1] = "End" $aArrayToSearch[$aArrayInArray[1] + Int(UBound($aArrayToFind, $UBOUND_ROWS) / 2)][$aArrayInArray[2] + Int(UBound($aArrayToFind, $UBOUND_COLUMNS) / 2)] = "(Approx) Center" _ArrayDisplay($aArrayToSearch, "ArrayInArray") ElseIf ($aArrayInArray[0] > 1) Then MsgBox("", "Multiple Matches", "Multiple Matches Found For Search") Else MsgBox("", "No Matches", "No Matches Found For Search") EndIf EndIf EndFunc ;==>Start Func ArrayInArray($aArrayToSearch, $aArrayToFind) Local $aReturn[3] = [0, -1, -1] If (Not IsArray($aArrayToSearch)) Then Return SetError(1, 0, $aReturn) If (Not IsArray($aArrayToFind)) Then Return SetError(2, 0, $aReturn) Local $iRowsToSearch = UBound($aArrayToSearch, $UBOUND_ROWS) Local $iColumnsToSearch = UBound($aArrayToSearch, $UBOUND_COLUMNS) Local $iRowsToFind = UBound($aArrayToFind, $UBOUND_ROWS) Local $iColumnsToFind = UBound($aArrayToFind, $UBOUND_COLUMNS) If ($iRowsToFind > $iRowsToSearch) Then Return SetError(3, 0, $aReturn) If ($iColumnsToFind > $iColumnsToSearch) Then Return SetError(4, 0, $aReturn) For $iRow = 0 To $iRowsToSearch - $iRowsToFind For $iColumn = 0 To $iColumnsToSearch - $iColumnsToFind Local $bValid = False For $i = 0 To $iRowsToFind - 1 For $p = 0 To $iColumnsToFind - 1 If ($aArrayToFind[$i][$p] = "" Or $aArrayToFind[$i][$p] = $aArrayToSearch[$iRow + $i][$iColumn + $p]) Then $bValid = True Else $bValid = False ExitLoop 2 EndIf Next Next If ($bValid) Then ; Number of valid results found $aReturn[0] += 1 ; row of the last valid result found $aReturn[1] = $iRow ; column of the last valid result found $aReturn[2] = $iColumn EndIf Next Next Return $aReturn EndFunc ;==>ArrayInArray ArrayInArray Returns an array: [0] = number of results found, [1] = row of the last valid result found, [2] = column of the last valid result found
  11. Hi everybody, i have a question related to strings items in an Array and sorting. Maybe someone can advice me how to solve the issue. I have an Array of strings, every item of the Array is as following: INFO [13.06.2017 11:48:01] [Thread-13] [ConGenImpUsb -> waitForConnection] INFO [07.06.2017 08:55:44] [main] MDU5 - Ver 5.1x I want to sort the item in the array by date and time, is there any function which allows me to sort by date/time? Thanks in advance
  12. Hello everyone I would like to have some help regarding my issue. I am trying to extract some information from excel sheet, I use _Excel_RangeFind then I get the array for the value then I check the array. In case the array is true the next will be to get some information based on the extracted array if no array because the value is not found it gives a messages box that the value is not found. My problem that the button works for one time only if i tried any value which exist in the sheet it gives me that value not found. I suspect that there is a problem regarding While loop. here is my code #include <GUIConstantsEx.au3> #include <WinAPI.au3> #Include <GuiListBox.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <Excel.au3> #include <MsgBoxConstants.au3> #include <ExcelConstants.au3> if FileExists ("result.txt") Then Sleep (100) Else readxl() EndIf Global $oExcel = _Excel_Open(False,False) If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeFind Example", "Error creating the Excel application object." & @CRLF & "@error = " & @error & ", @extended = " & @extended) Global $oWorkbook = _Excel_BookOpen($oExcel, "D:\info.xlsx",False,False) If @error Then MsgBox($MB_SYSTEMMODAL, "Excel Error", "Error opening workbook '" & $oWorkbook & @CRLF & "@error = " & @error & ", @extended = " & @extended) _Excel_Close($oExcel) Exit EndIf Local $lab1 = _Excel_RangeRead($oWorkbook, Default,"B1") Local $lab2 = _Excel_RangeRead($oWorkbook, Default,"C1") Local $lab3 = _Excel_RangeRead($oWorkbook, Default,"D1") Local $lab4 = _Excel_RangeRead($oWorkbook, Default,"E1") Global $sResult1,$sResult2,$sResult3,$sResult4,$sResult5,$sResult6 Global $asKeyWords = stringsplit (FileRead (@ScriptDir & "\result.txt"),@CRLF) Global Const $xlUp = -4162 ;~ _Main() Local $hGUI, $hList, $hInput, $aSelected, $sChosen, $hUP, $hDOWN, $hENTER, $hESC Local $sCurrInput = "", $aCurrSelected[2] = [-1, -1], $iCurrIndex = -1, $hListGUI = -1 $hGUI = GUICreate("Rimo System", 253, 270, 192, 124) Global $hInput = GUICtrlCreateInput("", 24, 48, 169, 21) Global $Label1 = GUICtrlCreateLabel("Rimo System", 80, 16, 150, 25) GUICtrlSetFont(-1, 14, 800, 0, "MS Serif") Global $Input2 = GUICtrlCreateInput("", 72, 144, 161, 21) Global $Input3 = GUICtrlCreateInput("", 72, 176, 161, 21) Global $Input4 = GUICtrlCreateInput("", 72, 208, 161, 21) Global $Input5 = GUICtrlCreateInput("", 72, 240, 161, 21) $Input6 = GUICtrlCreateInput("", 72, 272, 161, 21) $Input7 = GUICtrlCreateInput("", 72, 304, 161, 21) $Button1 = GUICtrlCreateButton("Get Info", 72, 88, 89, 33) $Label2 = GUICtrlCreateLabel("Label2", 16, 144, 36, 17) GUICtrlSetData( -1,$lab1) $Label3 = GUICtrlCreateLabel("Label3", 16, 176, 36, 17) GUICtrlSetData( -1,$lab2) $Label4 = GUICtrlCreateLabel("Label4", 16, 208, 36, 17) GUICtrlSetData( -1,$lab3) $Label5 = GUICtrlCreateLabel("Label5", 16, 240, 36, 17) GUICtrlSetData( -1,$lab4) $Label6 = GUICtrlCreateLabel("", 16, 272, 36, 17) $Label7 = GUICtrlCreateLabel("", 16, 304, 36, 17) $Button2 = GUICtrlCreateButton("Cancel", 112, 416, 121, 25) GUISetState(@SW_SHOW, $hGUI) Global $sSearch = guictrlread ($hInput) $hUP = GUICtrlCreateDummy() $hDOWN = GUICtrlCreateDummy() $hENTER = GUICtrlCreateDummy() $hESC = GUICtrlCreateDummy() Dim $AccelKeys[4][2] = [["{UP}", $hUP], ["{DOWN}", $hDOWN], ["{ENTER}", $hENTER], ["{ESC}", $hESC]] GUISetAccelerators($AccelKeys) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $Button2 Exit Case $Button1 Global $aResult = _Excel_RangeFind($oWorkbook, guictrlread($hInput) ,"A2:A2000") Global $aExtract = _ArrayExtract($aResult, 0, 0, 2, 2) if _elementExists($aExtract,0) Then getdata() Else MsgBox(0,"","Value Does Not Exist") EndIf Case $hESC If $hListGUI <> -1 Then ; List is visible. GUIDelete($hListGUI) $hListGUI = -1 Else ExitLoop EndIf Case $hUP If $hListGUI <> -1 Then ; List is visible. $iCurrIndex -= 1 If $iCurrIndex < 0 Then $iCurrIndex = 0 EndIf _GUICtrlListBox_SetCurSel($hList, $iCurrIndex) EndIf Case $hDOWN If $hListGUI <> -1 Then ; List is visible. $iCurrIndex += 1 If $iCurrIndex > _GUICtrlListBox_GetCount($hList) - 1 Then $iCurrIndex = _GUICtrlListBox_GetCount($hList) - 1 EndIf _GUICtrlListBox_SetCurSel($hList, $iCurrIndex) EndIf Case $hENTER If $hListGUI <> -1 And $iCurrIndex <> -1 Then ; List is visible and a item is selected. $sChosen = _GUICtrlListBox_GetText($hList, $iCurrIndex) EndIf Case $hList $sChosen = GUICtrlRead($hList) EndSwitch Sleep(10) $aSelected = _GetSelectionPointers($hInput) If GUICtrlRead($hInput) <> $sCurrInput Or $aSelected[1] <> $aCurrSelected[1] Then ; Input content or pointer are changed. $sCurrInput = GUICtrlRead($hInput) $aCurrSelected = $aSelected ; Get pointers of the string to replace. $iCurrIndex = -1 If $hListGUI <> -1 Then ; List is visible. GUIDelete($hListGUI) $hListGUI = -1 EndIf $hList = _PopupSelector($hGUI, $hListGUI, _CheckInputText($sCurrInput, $aCurrSelected)) ; ByRef $hListGUI, $aCurrSelected. EndIf If $sChosen <> "" Then GUICtrlSendMsg($hInput, 0x00B1, $aCurrSelected[0], $aCurrSelected[1]) ; $EM_SETSEL. _InsertText($hInput, $sChosen) $sCurrInput = GUICtrlRead($hInput) GUIDelete($hListGUI) $hListGUI = -1 $sChosen = "" EndIf WEnd GUIDelete($hGUI) Func _CheckInputText($sCurrInput, ByRef $aSelected) Local $sPartialData = "" If (IsArray($aSelected)) And ($aSelected[0] <= $aSelected[1]) Then Local $aSplit = StringSplit(StringLeft($sCurrInput, $aSelected[0]), " ") $aSelected[0] -= StringLen($aSplit[$aSplit[0]]) If $aSplit[$aSplit[0]] <> "" Then For $A = 1 To $asKeyWords[0] If StringLeft($asKeyWords[$A], StringLen($aSplit[$aSplit[0]])) = $aSplit[$aSplit[0]] And $asKeyWords[$A] <> $aSplit[$aSplit[0]] Then $sPartialData &= $asKeyWords[$A] & "|" EndIf Next EndIf EndIf Return $sPartialData EndFunc ;==>_CheckInputText Func _PopupSelector($hMainGUI, ByRef $hListGUI, $sCurr_List) Local $hList = -1 If $sCurr_List = "" Then Return $hList EndIf $hListGUI = GUICreate("", 280, 160, 23, 62, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_MDICHILD), $hMainGUI) $hList = GUICtrlCreateList("", 0, 0, 170, 150, BitOR(0x00100000, 0x00200000)) GUICtrlSetData($hList, $sCurr_List) GUISetControlsVisible($hListGUI) ; To Make Control Visible And Window Invisible. GUISetState(@SW_SHOWNOACTIVATE, $hListGUI) Return $hList EndFunc ;==>_PopupSelector Func _InsertText(ByRef $hEdit, $sString) #cs Description: Insert A Text In A Control. Returns: Nothing #ce Local $aSelected = _GetSelectionPointers($hEdit) GUICtrlSetData($hEdit, StringLeft(GUICtrlRead($hEdit), $aSelected[0]) & $sString & StringTrimLeft(GUICtrlRead($hEdit), $aSelected[1])) Local $iCursorPlace = StringLen(StringLeft(GUICtrlRead($hEdit), $aSelected[0]) & $sString) GUICtrlSendMsg($hEdit, 0x00B1, $iCursorPlace, $iCursorPlace) ; $EM_SETSEL. EndFunc ;==>_InsertText Func _GetSelectionPointers($hEdit) Local $aReturn[2] = [0, 0] Local $aSelected = GUICtrlRecvMsg($hEdit, 0x00B0) ; $EM_GETSEL. If IsArray($aSelected) Then $aReturn[0] = $aSelected[0] $aReturn[1] = $aSelected[1] EndIf Return $aReturn EndFunc ;==>_GetSelectionPointers Func GUISetControlsVisible($hWnd) ; By Melba23. Local $aControlGetPos = 0, $hCreateRect = 0, $hRectRgn = _WinAPI_CreateRectRgn(0, 0, 0, 0) Local $iLastControlID = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle(-1)) For $i = 3 To $iLastControlID $aControlGetPos = ControlGetPos($hWnd, '', $i) If IsArray($aControlGetPos) = 0 Then ContinueLoop $hCreateRect = _WinAPI_CreateRectRgn($aControlGetPos[0], $aControlGetPos[1], $aControlGetPos[0] + $aControlGetPos[2], $aControlGetPos[1] + $aControlGetPos[3]) _WinAPI_CombineRgn($hRectRgn, $hCreateRect, $hRectRgn, 2) _WinAPI_DeleteObject($hCreateRect) Next _WinAPI_SetWindowRgn($hWnd, $hRectRgn, True) _WinAPI_DeleteObject($hRectRgn) EndFunc Func _elementExists($array, $element) If $element > UBound($array)-1 Then Return False ; element is out of the array bounds Return True ; element is in array bounds EndFunc Func getdata() ;~ Local $sResult1 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","B")) ;~ Local $sResult2 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","C")) ;~ Local $sResult3 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","D")) ;~ Local $sResult4 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","E")) ;~ Local $sResult5 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","F")) ;~ Local $sResult6 = _Excel_RangeRead($oWorkbook, Default,StringReplace(StringReplace ($aExtract[0],"$",""),"A","G")) guictrlsetdata($Input2,$sResult1) guictrlsetdata($Input3,$sResult2) guictrlsetdata($Input4,$sResult3) guictrlsetdata($Input5,$sResult4) guictrlsetdata($Input6,$sResult5) guictrlsetdata($Input7,$sResult6) _Excel_Close($oExcel,Default,True) EndFunc Func readxl() Global $oExcel = _Excel_Open(False,False) If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeFind Example", "Error creating the Excel application object." & @CRLF & "@error = " & @error & ", @extended = " & @extended) Global $oWorkbook = _Excel_BookOpen($oExcel, "D:\info.xlsx",False,False) LOcal Const $xlUp = -4162 With $oWorkbook.ActiveSheet ; process active sheet $oRangeLast = .UsedRange.SpecialCells($xlCellTypeLastCell) ; get a Range that contains the last used cells $iRowCount = .Range(.Cells(1, 1), .Cells($oRangeLast.Row, $oRangeLast.Column)).Rows.Count ; get the the row count for the range starting in row/column 1 and ending at the last used row/column $iLastCell = .Cells($iRowCount + 1, "B").End($xlUp).Row ProgressOn("Copying Cells", "Copying Cells progress", "0%") For $i = 2 to $iLastCell Local $total = Int(($i/$iLastCell)*100) Local $sResult3 = _Excel_RangeRead($oWorkbook, Default, "A" & $i) FileWriteLine("result.txt",$sResult3) ProgressSet(($i/$iLastCell)*100, $total & "%") Next ;~ FileWrite("result.txt",$sResult3) ProgressSet(100, "Done", "Complete") Sleep (1500) ProgressOff() _Excel_Close($oExcel,Default,True) EndWith EndFunc
  13. Hello, i'm making a little script that lets users enter a question and if the script can't answer to, it ask what would be the answer (a bit like siri on IPhones). And I try to display the "supposed array" I still have an error.. I searched on Google and got nothing looked in the help file too.. I'm here to know if someone have a solution to my error please. Here is where $a and $b should become arrays : Dim $dossier = @AppDataDir & "\Siri2" Dim $chemin = $dossier & "\data.ini" Global $a = _InfoRead($chemin, 0) Global $b = _InfoRead($chemin, 1) with this function : Func _InfoRead($path, $mode = 0) If DirGetSize($dossier) = -1 Then Return SetError(-4) If Not FileExists($chemin) Then Return SetError(-5) Local $readed = IniReadSection($path, "data") If @error Then Return SetError(-3) $size = $readed[0][0] Local $return[$size] For $i = 1 To $size Step 1 $return[$i - 1] = $readed[$i][$mode] Next Return $return EndFunc and the thing that i don't understand is that, after _InfoRead return affected to $a, I can't use _ArrayDisplay because of error 1 "$aArray is not an array" (and same fpr the variable $b).. Can please someone help me to understand why is it doing this ? -hcI
  14. Super simple super quick script I made to randomize teams for mixed doubles. Haven't coded for a while so it felt good to write anything. #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <SliderConstants.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <Array.au3> #include <Excel.au3> Local $arraySize = 2 local $array1[50] = ["Doug","Julio"] local $array2[50] = ["Hannah","Sheila"] Local $oBook #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Doubles Team Mixer", 615, 438, 192, 124) $Bachround = GUICtrlCreatePic("C:\Users\a607150\Pictures\2.jpg",0,0,615,438) $Input1 = GUICtrlCreateInput("", 64, 128, 121, 175) $Input2 = GUICtrlCreateInput("", 364, 128, 121, 175) $Button1 = GUICtrlCreateButton("Serve",216,140,121,42) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 $array1 = GUICtrlRead($input1) $array1 = StringSplit($array1,",") $array2 = GUICtrlRead($input2) $array2 = StringSplit($array2,",") _ArrayDelete($array1,0) _ArrayDelete($array2,0) _ArrayShuffle($array2) $oBook = _Excel_Open(Default, Default, Default, Default, True) $oWorkBook = _Excel_BookNew($oBook, 1) _Excel_RangeWrite($oWorkBook,$oWorkBook.activesheet,"Guys","A1") _Excel_RangeWrite($oWorkBook,$oWorkBook.activesheet,"Gals","B1") _Excel_RangeWrite($oWorkBook,$oWorkBook.activesheet,$array1,"A2") If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeWrite Example 2", "Error writing $array1 to worksheet." & @CRLF & "@error = " & @error & ", @extended = " & @extended) _Excel_RangeWrite($oWorkBook,$oWorkBook.activesheet,$array2,"B2") EndSwitch WEnd
  15. I posted this the other day, but thought I would post in a separate topic instead. #include <MsgBoxConstants.au3> ; ---- Start of Person Class ; Stored in the 'object' to verify it's our 'object' and not some random array Global Const $PERSON_GUID = '4197B285-6AB1-489B-8585-08C852E33F3D' ; Friendly names for 0, 1, 2 and 3 Global Enum $PERSON_AGE, $PERSON_NAME, $PERSON_ID, $PERSON_MAX ; Constructor Func Person($sName, $iAge) Local $hPerson[$PERSON_MAX] ; Set the GUID, so as the verification will work $hPerson[$PERSON_ID] = $PERSON_GUID Person_SetAge($hPerson, $iAge) Person_SetName($hPerson, $sName) ; Return the Person 'object' Return $hPerson EndFunc ;==>Person ; Getter for the age property Func Person_GetAge(ByRef $hPerson) Return _Person_IsObject($hPerson) ? $hPerson[$PERSON_AGE] : Null EndFunc ;==>Person_GetAge ; Setter for the age property Func Person_SetAge(ByRef $hPerson, $iAge) ; If not a valid 'object' or integer then return If Not _Person_IsObject($hPerson) Or Not IsInt($iAge) Then Return ; Set the age $hPerson[$PERSON_AGE] = $iAge EndFunc ;==>Person_SetAge ; Getter for the name property Func Person_GetName(ByRef $hPerson) Return _Person_IsObject($hPerson) ? $hPerson[$PERSON_NAME] : Null EndFunc ;==>Person_GetName ; Setter for the name property Func Person_SetName(ByRef $hPerson, $sName) ; If not a valid 'object' then return If Not _Person_IsObject($hPerson) Then Return ; Set the name $hPerson[$PERSON_NAME] = $sName EndFunc ;==>Person_SetName ; ToString() for the 'object' Func Person_ToString(ByRef $hPerson) Return _Person_IsObject($hPerson) ? StringFormat('Name: %s, Age: %i', $hPerson[$PERSON_NAME], $hPerson[$PERSON_AGE]) : Null EndFunc ;==>Person_ToString ; Check if it's a valid 'object' and not some random array. "NTERNAL ONLY! Func _Person_IsObject(ByRef $hPerson) Return UBound($hPerson) = $PERSON_MAX And $hPerson[$PERSON_ID] == $PERSON_GUID EndFunc ;==>_Person_IsObject ; ---- End of Person Class Example() Func Example() ; Store the Person 'object', which is just a glorified array Local $hP1 = Person('John', 30) ; Display the 'object' MsgBox($MB_SYSTEMMODAL, 'Person 1', Person_ToString($hP1)) ; Create a new person ; Store the Person 'object', which is just a glorified array Local $hP2 = Person('James', 36) ; Display the 'object' MsgBox($MB_SYSTEMMODAL, 'Person 2', Person_ToString($hP2)) ; Set the age for Person 2 Person_SetAge($hP2, 45) ; Display the 'object' MsgBox($MB_SYSTEMMODAL, 'Person 2 - Revised', Person_ToString($hP2)) EndFunc ;==>Example
  16. Good evening I was looking around the forum if I could find a function that allows to convert a string into a 2 dimensional array... The first column of the array is always the same, but the rows could change... I have a pattern like: Column A|Column B Static Text 1|Data 1 Static Text 2|Data 2 Static Text 3|Data 3 Static Text 4|Data 4 Where, Static Text (1...4) will be always the same, and I don't want to change them... But, Data 1...4 are dynamic fields... So, I could have the pattern above AND I coould have the pattern I'm going to show you right below Column A|Column B Static Text 1|Data 1 Static Text 2|Data 2 Static Text 3|Data 3 Static Text 4|Data 4 Static Text 1|Data 5 Static Text 2|Data 6 Static Text 3|Data 7 Static Text 4|Data 8 How can I do in this case? Thanks for everyone's help
  17. Hi all, I have the following code, basically, it populates an array with unique characters found in a string, but it turns out only one character is in the array, i don't want to think it is due to a bug of autoit at this point, so i need your help on why, please Dim $sx[0] Dim $cn $ss = "Xx" ConsoleWrite(StringLeft($ss, 1) & " " & StringRight($ss, 1) & @CRLF) ConsoleWrite(StringLeft($ss, 1) = StringRight($ss, 1) & @CRLF) ;here show X <> x ConsoleWrite(@CRLF) ;the following is to populate array $sx with different unique characters in $ss For $b = 1 To StringLen($ss) $flg = 0 For $a = 0 To UBound($sx) - 1 ;if asc(StringMid($ss,$b,1)) = asc($sx[$a]) Then ;if this line is used instead of the next, everything is fine If StringMid($ss, $b, 1) = $sx[$a] Then If StringMid($ss, $b, 1) = "x" Then ConsoleWrite("<<->>" & StringMid($ss, $b, 1) & " " & $sx[$a] & @CRLF) $flg = 1 ExitLoop EndIf Next If $flg = 0 Then $cn = $cn + 1 ReDim $sx[$cn] $sx[$cn - 1] = StringMid($ss, $b, 1) EndIf Next ConsoleWrite(UBound($sx) & @CRLF);list the ubound of $sx ;list what is in array $sx For $a = 0 To UBound($sx) - 1 ConsoleWrite($sx[$a] & @CRLF) Next same code in a file is attached as uniqueChar2Array.au3
  18. I have a string with comma seperated as below. Name="Test-win10x64,Test-win10x65,Test-win10x67" $machine_names = StringSplit($tempINIValue, ',', $STR_ENTIRESPLIT) with the above line i can get a single dimension array. But I want a tabular format array like 4X4 where I want to add the 4 single dimension arrays as different columns in them. Is there any option to do the same.
  19. im getting strange output in array display,$split_[1] is not properly aligned to other arrays and why guictrlsetdata is not writting any data if i put comma(,) at the end of the text in $Input1??? #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #Region ### START Koda GUI section ### Form=C:\Users\user\Desktop\Script\StringSplit.kxf $Form1 = GUICreate("Form1", 623, 449, 192, 114) $Input1 = GUICtrlCreateInput("50UGITQ421X, 50UGITQ422X, 50UGITQ423X, 50UGITQ427X, 50UGITQ431X, 50UGITQ435X, 50UGITQ436X, 50UGITQ437X, 50UGITQ441X, 50UGITQ445X, 50UGITQ449X, 50UGITQ453X, 50UGITQ454X, 50UGITQ455X, 50UGITQ459X", 24, 16, 553, 21) $Split = GUICtrlCreateButton("Split", 24, 48, 75, 25) $List1 = GUICtrlCreateList("", 24, 96, 553, 97) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Split $read = GUICtrlRead($Input1) $split_ = StringSplit($read, ",") $Max = UBound($split_, 1) For $i = 1 To UBound($split_) - 1 ConsoleWrite($split_[$i] & @CRLF) ;~ ControlSetText($Form1, "", $List1, $split_[$i]) GUICtrlSetData($List1, $split_[$i]) ;~ GUICtrlSetData($List1, $split_[$i]) ;~ GUICtrlSetData($List1, $i) Next _ArrayDisplay($split_) EndSwitch WEnd
  20. Hey ! I was looking for an array display to see the result of StringSplit but when i called the <Array.au3>, an error is showing up when i try to launch the script. I took a screenshoot of the windows dialog box error : imp.bmp And when I look into the Array.au3 there is no error : Why is it doing this ?
  21. I was reading a recent post about converting a 2D array into a 1D array. The OP, from my understanding, more-or-less wanted to extract a single column of data and format it in a 1D array. The solutions were proper and efficient compared to what I wanted to share, but I figured I'd share as it's a good lesson and a neat, purely mathematical approach to mapping an index to a 2D array. As-is, this only works for 2D arrays. By knowing how big a 2D array is, an index can be calculated for each indices/subscript. The functions below define a random sized 2D array, and calculate an index that matches the indices on the 2D array. #include "Array.au3" $iRow = Random(2,10,1) $iCol = Random(2,10,1) $iRandomIndex = Random(0,($iRow*$iCol)-1,1) $sIndicies = _IndexTo2DIndicies($iRandomIndex, $iRow, $iCol) _2DArrayTo1DIndexes($iRow, $iCol, $iRandomIndex & " = $aArr" & $sIndicies) Func _2DArrayTo1DIndexes($iRow = 1, $iCol = 1, $sMsg = Default) $iRow = Int($iRow) $iCOl = Int($iCol) Local $aData[$iRow][$iCol] For $iY = 0 to $iRow - 1 For $iX = 0 to $iCol - 1 Local $iIndex ;Index = ($iColMax * $iY) + $iX $aData[$iY][$iX] = ($iCol * $iY) + $iX Next Next If $sMsg = Default Then $sMsg = "1D Indexes of 2D Array Indicies" _ArrayDisplay($aData,$sMsg) EndFunc Func _IndexTo2DIndicies($iIndex = 0, $iRow = 0, $iCol = 0) $iIndex = Int($iIndex) $iRow = Int($iRow) $iCol = Int($iCol) If $iIndex = 0 Then Return "[0][0]" If $iIndex >= $iRow * $iCol Then Return SetError(1,0,0) Local $iX = Mod($iIndex, $iCol) ;Local $iY = ($iIndex-$iX) / $iCol Local $iY = Int($iIndex / $iCol) ;Thanks Chimp Return "[" & $iY & "][" & $iX & "]" EndFunc I used this type of approach before with a pixel array. I had a 1D array for storing individual pixel information, then mapped the pixels to an X|Y grid (2D array or XY coords). Now if the purpose is just to flatten an array, the most efficient way I am aware of would be to create a new 1D array the size of the total number of indices in the 2D array (RowMax * ColMax), and loop through the array. I suppose these methods (above) would be particularly useful if you need to randomly or programmatically access indices in a non-linear fashion. Anyways, just wanted to share a fun exercise with arrays.
  22. Hi, I have a 2D array with 2 columns, the 1st column contains a "version string" and the 2nd column contains a generic string. I want to sort it in the descending order so the latest version comes first. #include <Array.au3> Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]] _ArraySort($aVersionsAndReleases, 1) ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - ')) _ArrayDisplay($aVersionsAndReleases) Unfortunately, _ArraySort isn't working here . This is the output generated by the script: 0.2.9.11 - Release #4 0.2.9.10 - Release #3 0.2.8.9 - Release #1 0.2.8.10 - Release #2 The expected result should be: 0.2.9.11 - Release #4 0.2.9.10 - Release #3 0.2.8.10 - Release #2 0.2.8.9 - Release #1 I am looking to develop an function which does this... but I don't know where to start . Can someone help me get started? Thanks in Advance! - TD.
  23. ArrayWorkshop is what I like to think of as the 'Leibnitzian' approach to multidimensional arrays: formulaic beyond 3 dimensions. Most of the functions allow you to target the dimension in which you want processing to be done. It shouldn't take too long to figure out how this works after you've run some examples. _ArrayAttach treats multidimensional arrays as if they were lego bricks - any array can be attached regardless of bounds or dimensions. #include-once ; #INDEX# ====================================================================================================================== ; Title .........: ArrayWorkshop [version 1.0.1] ; AutoIt Version : 3.3.14.2 ; Language ......: English ; Description ...: Multidimensional array functions. ; Notes .........: In this library, an array region is defined as follows: ; 1. items within a one dimensional array ; 2. lists within a two dimensional array (rows or columns) ; 3. tables within a three dimensional array ; 4. cuboidal areas within a four dimension array ; 5. four dimensional cuboids within a five dimensional array ; etc... ; To reduce bloat, several functions access part of the script referred to (in the comments) as 'Remote Loops'. ; Arrays containing zero elements are not supported and will cause functions to return an error. ; Limiting the number of dimensions to single digits was a practical decision to simplify syntax. ; Credit must go to fellow AutoIt forum members whose code or suggestions have been influential in the ; development of these functions: Jos van der Zande, jguinch, jchd, LazyCoder, Tylo, Ultima, Melba23, BrewManNH ; The above list is not exhaustive, nor are the names in any particular order. ; Author(s) .....: czardas ; ============================================================================================================================== ; #CURRENT# ==================================================================================================================== ; _ArrayAttach [limit = 9 dimensions] ; _ArraySortXD [limit = 9 dimensions] ; _ArrayTransform [limit = 9 dimensions] ; _ArrayUniqueXD [limit = 9 dimensions] ; _DeleteDimension [limit = 9 dimensions] ; _DeleteRegion [limit = 9 dimensions] ; _ExtractRegion [limit = 9 dimensions] ; _InsertRegion [limit = 9 dimensions] ; _PreDim [limit = 9 dimensions] ; _ReverseArray [limit = 9 dimensions] ; _SearchArray [limit = 9 dimensions] ; _ShuffleArray [limit = 9 dimensions] ; ============================================================================================================================== ; #INTERNAL_USE_ONLY#=========================================================================================================== ; __AcquireExponent, __CreateTrac, __ExtractVector, __FindExact, __FindExactCase, __FindString, __FindStringCase, __FindWord, ; __FindWordCase __FloodFunc, ___FloodXD, ___FormatNum, __GetBounds, __HiddenIndices, ___Search1D, ___NewArray, ___NumCompare, ; __QuickSort1D, __QuickSortXD, __ResetBounds, ___Reverse1D, __Separate1D, __Separate256, __SeparateXD, __Shuffle1D, ; __ShuffleXD , __TagSortSwap, __TagSortSwapXD ; ============================================================================================================================== #Au3Stripper_Off Global $g__ARRWSHOP_RESUME = True ; prevents certain processes from running when set to False [do not use in your script] Global Const $g__ARRWSHOP_SUB = ChrW(57344) ; [U+E000] ; #FUNCTION# =================================================================================================================== ; Name...........: _ArrayAttach ; Description ...: Joins two arrays together. ; Syntax.........: _ArrayAttach($aTarget, $aSource [, $iDimension = 1]) ; Parameters.....; $aTarget - [ByRef] Target array to which the source array (or data) will be concatenated. ; $aSource - The array to attach to the target. ; $iDimension - [Optional] Integer value - the dimension in which concatenation occurs. Default = 1st dimension ; Return values .: Success - Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 $aTarget is not a valid array. ; |@error = 2 Dimension limit exceeded. ; |@error = 3 Arrays must contain at least one element. ; |@error = 4 Output array size exceeds AutoIt limits. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; Extra dimensions are added to the target when: ; 1. the source array has more dimensions than the target [or] ; 2. the 3rd parameter ($iDimension) is greater than the number of dimensions available. ; ============================================================================================================================== Func _ArrayAttach(ByRef $aTarget, $aSource, $iDimension = 1) If Not IsArray($aTarget) Then Return SetError(1) ; the target must be an array Local $aBoundSrc[1] If Not IsArray($aSource) Then ; convert $aSource into an array $aBoundSrc[0] = $aSource ; use $aBoundSrc as a temporary array to preserve memory $aSource = $aBoundSrc ; conversion by assignment EndIf $aBoundSrc = __GetBounds($aSource, 9) ; get the bounds of the source array If @error Then Return SetError(3) ; $aSource must contain at least one element Local $aBoundTgt = __GetBounds($aTarget, 9) ; get the bounds of the target array If @error Then Return SetError(3) ; $aTarget must contain at least one element $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $aBoundTgt[0] > 9 Or $aBoundSrc[0] > 9 Or $iDimension > 9 Or $iDimension < 1 Then Return SetError(2) ; dimension limit exceeded Local $iDim = ($aBoundSrc[0] > $aBoundTgt[0]) ? $aBoundSrc[0] : $aBoundTgt[0] ; minimum number of dimensions needed for the output If $iDimension > $iDim Then $iDim = $iDimension ; the specified dimension may not yet exist Local $aBoundNew[$iDim + 1] ; output bounds $aBoundNew[0] = $iDim ; element 0 contains the number of dimensions For $i = 1 To $iDim ; get the minimum bounds within all dimensions If $i <> $iDimension Then $aBoundNew[$i] = ($aBoundSrc[$i] > $aBoundTgt[$i]) ? $aBoundSrc[$i] : $aBoundTgt[$i] Else ; expansion within the explicit dimension is determined differently $aBoundNew[$i] = $aBoundSrc[$i] + $aBoundTgt[$i] ; add the number of sub-indices together EndIf $aBoundSrc[$i] -= 1 ; convert to the final index value in each dimension of the source array Next Local $iCount = 1 ; check output bounds remain within range For $i = 1 To $aBoundNew[0] $iCount *= $aBoundNew[$i] If $iCount > 16777216 Then Return SetError(4) ; output array size exceeds AutoIt limits Next _PreDim($aTarget, $iDim) ; add more dimensions if needed __ResetBounds($aTarget, $aBoundNew) ; ReDim the target to make space for more elements If $iDim = 1 Then ; [do not send to remote loop region] For $iRegion = $aBoundTgt[$iDimension] To $aBoundNew[$iDimension] - 1 ; to the new bounds of the [only] dimension $aTarget[$iRegion] = $aSource[$iRegion - $aBoundTgt[$iDimension]] Next Return EndIf Local $sTransfer = '$aSource' & __HiddenIndices($aBoundSrc[0], $iDimension), _ ; to access elements at their original indices $iFrom, $aFloodFill = __FloodFunc() $aBoundSrc[$iDimension] = 0 ; whichever loop this relates to must only run once on each encounter For $iRegion = $aBoundTgt[$iDimension] To $aBoundNew[$iDimension] - 1 ; to the new bounds of the specified dimension $iFrom = $iRegion - $aBoundTgt[$iDimension] ; adjusted to begin transfer from source element 0 $aFloodFill[$iDim]($aTarget, $aBoundSrc, $iDimension, $iRegion, $iFrom, $aSource, $sTransfer) ; flood the region Next EndFunc ;==>_ArrayAttach ; #FUNCTION# =================================================================================================================== ; Name...........: _ArraySortXD ; Description ...: Sorts multidimensional arrays according to miscellaneous criteria. ; Syntax.........: _ArraySortXD($aArray [, $iDimension = 1 [, $iAlgorithm = 0 [, $iEnd = -1 [, $1 = 0 [, $2 = 0 ], etc... ]]]] ; Parameters.....; $aArray - [ByRef] The array to sort. ; $iDimension - [Optional] Integer value - the dimension in which sorting occurs. Default = 1st dimension ; $iAlgorithm - [Optional] Integer value - defines the sorting criteria. Default = lexical [see comments] ; $iEnd - [Optional] Integer value - final index to stop sorting (within the explicit dimension). Default = -1 ; $1, $2, $3, $4, $5, $6, $7, $8, $9 - [Optional] - start sub-indices within each dimension. [see comments] ; Return values .: Success - Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 The first parameter is not a valid array. ; |@error = 2 Array does not contain any elements. ; |@error = 3 Dimension does not exist. ; |@error = 4 Out of range start parameter detected. ; |@error = 5 Out of range $iEnd value detected. ; |@error = 6 Bad algorithm detected. ; Author ........: czardas ; Comments ......; The algorithm parameter is binary flag. You can combine any of the following values: ; $iAlgorithm = 0 - alphabetical (lexical - applies to all items including numbers) ; $iAlgorithm = 1 - descending (applies to sorted items only) ; $iAlgorithm = 2 - numeric (applies to numbers only) ; $iAlgorithm = 4 - alphanumeric (applies to all items - overrides flag 2) ; $iAlgorithm = 256 - sort decimal strings by magnitude (combine with flags 2 and 4) ; $iAlgorithm = 512 - maintain original sequence of non-numeric items (only applies to flag 2) ; You can combine the various flags using BitOR() or you can also add them together. ; When sorting with flag 2, numbers always appear before unsorted items. ; When sorting with flag 4, numbers appear before non-numeric items in ascending order. ; Flag 256 will be ignored if not combined with flags 2 or 4. ; Flag 512 will be ignored if not combined with flag 2. ; ----------------------------------------------------------- ; Optional start sub-indices; $1, $2, $3, $4, $5, $6, $7, $8 and $9; work as follows: ; In the explicit dimension the start index should be less than $iEnd. ; In all other dimensions start values also represent end values. [range = 1, not multi-regional within XD] ; This function works for arrays of up to nine dimensions. ; ============================================================================================================================== Func _ArraySortXD(ByRef $aArray, $iDimension = 1, $iAlgorithm = 0, $iEnd = -1, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0) If Not IsArray($aArray) Then Return SetError(1) ; $aArray must be an array Local $aBound = __GetBounds($aArray) ; get the bounds of the array If @error Then Return SetError(2) ; $aArray must contain more than zero elements $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; dimension limit exceeded Local $aParam = [$aBound[0], $1, $2, $3, $4, $5, $6, $7, $8, $9] ; [$aParam can be oversized] For $i = 1 To $aBound[0] $aParam[$i] = ($aParam[$i] = Default) ? 0 : Int($aParam[$i]) If $aParam[$i] < 0 Or $aParam[$i] >= $aBound[$i] Then Return SetError(4) ; out of range start parameter was detected Next $iEnd = ($iEnd = -1 Or $iEnd = Default) ? $aBound[$iDimension] - 1 : Int($iEnd) Local $iStart = $aParam[$iDimension] If $iEnd <= $iStart Or $iEnd >= $aBound[$iDimension] Then Return SetError(5) ; meaningless $iEnd value $iAlgorithm = ($iAlgorithm = Default) ? 0 : Int($iAlgorithm) If BitAND(0xFFFFFCF8, $iAlgorithm) Then Return SetError(6) ; meaningless $iAlgorithm ; determine the type of algorithm Local $bNumeric = BitAND($iAlgorithm, 2) Or BitAND($iAlgorithm, 4), _ $bAlpha = BitAND($iAlgorithm, 4) Or Not $bNumeric, _ $bDecimals = $bNumeric And BitAND($iAlgorithm, 256), _ $bSequential = BitAND($iAlgorithm, 512) And BitAND($iAlgorithm, 2) And Not $bAlpha, _ $bReverse = Mod($iAlgorithm, 2) <> 0 Local $aTrac, $aVector, $iItems = 0 ; to count numeric elements [if needed] If $aBound[0] = 1 Then ; First deal with 1D arrays [optimized for algorithms 0, 2 and 4 without any other flags] If $bNumeric Then ; numeric [1D] If Not ($bDecimals Or $bSequential) Then ; tracking is not needed [conditional may require modification at some point to accomodate new algorithms] $iItems = __Separate1D($aArray, $iStart, $iEnd) ; place numbers before strings __QuickSort1D($aArray, $iStart, $iStart + $iItems - 1, 2) ; sort numbers numerically Else ; employ a track and trace mechanism $aTrac = __CreateTrac($aBound[$iDimension], $iStart, $iEnd) ; instead of sorting the array we will track migrating indices If $bDecimals Then $aVector = $aArray $iItems = __Separate256($aVector, $aTrac, $iStart, $iEnd) ; [numbers and decimal strings] __QuickSortXD($aVector, $aTrac, $iStart, $iStart + $iItems - 1, 256) ; pretend to sort the array but instead relocate indices in $aTrac $aVector = '' ; reduce memory usage ASAP Else ; [$bSequential = True] $iItems = __SeparateXD($aArray, $aTrac, $iStart, $iEnd) ; [numbers only] __QuickSortXD($aArray, $aTrac, $iStart, $iStart + $iItems - 1, 2) ; pretend to sort the array but instead relocate indices in $aTrac EndIf EndIf If $bAlpha Then If $bDecimals Then __QuickSortXD($aArray, $aTrac, $iStart + $iItems, $iEnd, 0) ; sort strings lexically Else __QuickSort1D($aArray, $iStart + $iItems, $iEnd, 0) ; sort strings lexically and finish If $bReverse Then ___Reverse1D($aArray, $iStart, $iEnd) ; descending Return ; finished EndIf ElseIf $bSequential Then __QuickSort1D($aTrac, $iStart + $iItems, $iEnd, 2) ; sort non-numeric element indices corrupted during separation ElseIf Not $bDecimals Then ; tracking was not used, so we are almost done here If $bReverse Then ___Reverse1D($aArray, $iStart, $iStart + $iItems - 1) ; descending Return ; finished EndIf If $bReverse Then ___Reverse1D($aTrac, $iStart, ($bAlpha ? $iEnd : $iStart + $iItems - 1)) ; reverse indices in $aTrac __TagSortSwap($aArray, $aTrac, $iStart, $iEnd) ; similar to the knight's tour problem Else ; lexical [1D] __QuickSort1D($aArray, $iStart, $iEnd, 0) If $bReverse Then ___Reverse1D($aArray, $iStart, $iEnd) ; descending EndIf Else ; multidimensional [XD] $aTrac = __CreateTrac($aBound[$iDimension], $iStart, $iEnd) ; used to track migrating indices $aVector = __ExtractVector($aArray, $iDimension, $aParam) ; first extract the vector to use for sorting (row or column etc...) ; now come similar arguments as for 1D If $bNumeric Then ; numeric [XD] $iItems = $bDecimals ? __Separate256($aVector, $aTrac, $iStart, $iEnd) : __SeparateXD($aVector, $aTrac, $iStart, $iEnd) __QuickSortXD($aVector, $aTrac, $iStart, $iStart + $iItems - 1, ($bDecimals ? 256 : 2)) ; relocate indices in $aTrac If $bAlpha Then __QuickSortXD($aVector, $aTrac, $iStart + $iItems, $iEnd, 0) ; sort strings lexically ElseIf $bSequential Then $aVector = '' ; free up memory __QuickSort1D($aTrac, $iStart + $iItems, $iEnd, 2) ; sort non-numeric element indices corrupted during separation EndIf $aVector = '' ; as above If $bReverse Then ___Reverse1D($aTrac, $iStart, ($bAlpha ? $iEnd : $iStart + $iItems - 1)) Else __QuickSortXD($aVector, $aTrac, $iStart, $iEnd, 0) ; relocate indices in $aTrac $aVector = '' ; as above If $bReverse Then ___Reverse1D($aTrac, $iStart, $iEnd) ; descending EndIf If $aBound[0] = 2 And $iDimension = 1 Then ; slightly more optimal method __TagSortSwapXD($aArray, $aTrac, $iStart, $iEnd) ; similar to the knight's tour problem Else $aParam = $aBound ; original parameters are no longer needed $aParam[$iDimension] = 1 Local $aRegion = ___NewArray($aParam) ; to store extracted regions For $i = 1 To $aParam[0] $aParam[$i] -= 1 Next Local $sIndices = __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]], _ $iCurr, $iNext, $sTransfer = '$aSource' & $sIndices ; array syntax ; [now comes the knight's tour in 9 dimensions] ;) For $iInit = $iStart To $iEnd ; initialize each swap sequence If $aTrac[$iInit] <> $iInit Then ; regions will now be overwritten in accordance with tracking information $iCurr = $iInit ; set the current region as the start of the sequence $fnFloodFill($aRegion, $aParam, $iDimension, 0, $iInit, $aArray, $sTransfer) ; extract region $sTransfer = '$aTarget' & $sIndices ; array syntax Do $fnFloodFill($aArray, $aParam, $iDimension, $iCurr, $aTrac[$iCurr], '', $sTransfer) ; overwrite each region in the sequence $iNext = $aTrac[$iCurr] ; get the next index in the sequence $aTrac[$iCurr] = $iCurr ; set to ignore overwritten regions on subsequent encounters $iCurr = $iNext ; follow the trail as far as it goes [index could be higher or lower] Until $aTrac[$iCurr] = $iInit ; all sequences end at this juncture $sTransfer = '$aSource' & $sIndices ; now we know where to put the initial region we copied earlier $fnFloodFill($aArray, $aParam, $iDimension, $iCurr, 0, $aRegion, $sTransfer) $aTrac[$iCurr] = $iCurr ; set to ignore on subsequent encounters [as above] EndIf Next EndIf EndIf EndFunc ;==>_ArraySortXD ; #FUNCTION# =================================================================================================================== ; Name...........: _ArrayTransform ; Description ...: Alters the shape of a multidimensional array without losing data. ; Syntax.........: _ArrayTransform($aArray [, $sShape = Default]) ; Parameters.....; $aArray - The array to modify. ; $sShape - [Optional] String or integer value - output dimension bounds sequence [See Comments] ; Return values .: Success - Returns the transformed array [ByRef]. ; Failure sets @error as follows: ; |@error = 1 The 1st parameter is not a valid array. ; |@error = 2 Bad $sShape parameter. ; Author ........: czardas ; Comments ......: The shape parameter must be a sequence of unique digits: each refering to a different dimension. ; For a 2D array the default shape parameter is '21', and for 3D it is '321' etc... ; The default output sequence transposes the array by reversing the dimension bounds ==> [7][8] becomes [8][7]. ; If you want a different output shape, change the dimension bounds sequence. ; eg. when $sShape = '2431', [1][2][3][4] will become [2][4][3][1] ; This function is limited to arrays of between two and nine dimensions. ; ============================================================================================================================== Func _ArrayTransform(ByRef $aArray, $sShape = Default) ; [default shape = reverse sequence '987654321'] If Not IsArray($aArray) Then Return SetError(1) ; not a valid array. Local $aBound = __GetBounds($aArray) If @error Or $aBound[0] = 1 Or $aBound[0] > 9 Then Return SetError(1) If $sShape = Default Then $sShape = StringRight('987654321', $aBound[0]) If StringLen($sShape) <> $aBound[0] Or Not StringIsDigit($sShape) Then Return SetError(2) ; bad $sShape parameter Local $aTrac = StringSplit($sShape, ''), $sTransfer = '$aSource' For $i = 1 To $aBound[0] If Not StringInStr($sShape, $i) Then Return SetError(2) ; bad $sShape parameter [dimensions must already exist] $sTransfer &= '[$a[' & $aTrac[$i] & ']]' ; default ==> '$aSource[$a[9]][$a[8]][$a[7]][$a[6]][$a[5]] etc...' Next Local $aBoundNew = $aBound __TagSortSwap($aBoundNew, $aTrac, 1, $aBoundNew[0]) Local $aNewArray = ___NewArray($aBoundNew), $fnFloodFill = __FloodFunc()[$aBound[0]] For $i = 1 To $aBoundNew[0] $aBoundNew[$i] -= 1 Next $fnFloodFill($aNewArray, $aBoundNew, 0, 0, '', $aArray, $sTransfer) $aArray = $aNewArray EndFunc ;==>_ArrayTransform ; #FUNCTION# =================================================================================================================== ; Name...........: _ArrayUniqueXD ; Description ...: Removes duplicate items from an array (or duplicate regions from a multidimensional array). ; Syntax.........: _ArrayUniqueXD($aArray [, $bCaseSense = False [, $iDimension = 1]]) ; Parameters.....; $aArray - The array containing duplicate regions to be removed. ; $bCaseSense - [Optional] Set to true for case sensitive matches. Default value = False ; $iDimension - [Optional] Integer value - the dimension to which uniqueness applies. Default = 1st dimension ; Return values .: Success - Returns the unique array [ByRef]. ; Failure sets @error as follows: ; |@error = 1 The 1st parameter is not an array. ; |@error = 2 The 1st parameter does not contain any elements. ; |@error = 3 The 3rd parameter is not a valid dimension. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; All elements within a region must be duplicated (in juxtaposed positions) before removal takes place. ; Integers of the same magnitude are treated as duplicates regardless of data type. ; This function does not remove regions containing objects, DLLStructs or other arrays. ; Example .......; _ArrayUniqueXD($aArray, Default, 2) ; [$iDimension = 2] ; ==> deletes duplicate COLUMNS from a 2D array ; ============================================================================================================================== Func _ArrayUniqueXD(ByRef $aArray, $bCaseSense = Default, $iDimension = 1) If Not IsArray($aArray) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array Local $aBound = __GetBounds($aArray, 9) If @error Then Return SetError(2) ; array contains zero elements $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) ; dimension does not exist If $aBound[$iDimension] < 2 Then Return ; the array is already unique For $i = 1 To 9 $aBound[$i] -= 1 ; set the max index in each dimension Next Local $sExpression = '$aArray' ; to access elements at their original indices For $i = 1 To $aBound[0] If $i <> $iDimension Then $sExpression &= '[$' & $i & ']' ; default expression = '$aArray[$iFrom][$2][$3][$4][$5] etc...' Else $sExpression &= '[$iFrom]' EndIf Next Local $sTransfer = '$aTarget' & __HiddenIndices($aBound[0], $iDimension), _ $fnFloodFill = __FloodFunc()[$aBound[0]], $iDim = $aBound[0], _ ; preserve this value $iItems = 0, $aFunction[1] = [0], $vElement, $iInt, $sName $aBound[0] = $aBound[$iDimension] ; the first loop will run to the bounds of the specified dimension $aBound[$iDimension] = 0 ; whichever loop this relates to must only run once on each encounter If $bCaseSense = Default Then $bCaseSense = False Local $oDictionary = ObjCreate("Scripting.Dictionary") For $iFrom = 0 To $aBound[0] $sName = '' ; clear previous name For $9 = 0 To $aBound[9] For $8 = 0 To $aBound[8] For $7 = 0 To $aBound[7] For $6 = 0 To $aBound[6] For $5 = 0 To $aBound[5] For $4 = 0 To $aBound[4] For $3 = 0 To $aBound[3] For $2 = 0 To $aBound[2] For $1 = 0 To $aBound[1] $vElement = Execute($sExpression) ; get the data contained in each element ; use non-hexadecimal characters (other than x) as datatype identifiers and convert the data to hexadecimal where necessary Switch VarGetType($vElement) Case 'String' If Not $bCaseSense Then $vElement = StringUpper($vElement) ; generates a case insensitive name segment $sName &= 's' & StringToBinary($vElement, 4) ; UTF8 [$SB_UTF8] Case 'Int32', 'Int64' ; use decimal without conversion ; the minus sign of a negative integer is replaced with 'g': to distinguish it from the positive value $sName &= ($vElement < 0) ? 'g' & StringTrimLeft($vElement, 1) : 'i' & $vElement Case 'Double' ; may be an integer $iInt = Int($vElement) $sName &= ($vElement = $iInt) ? (($iInt < 0) ? 'g' & StringTrimLeft($iInt, 1) : 'i' & $iInt) : 'h' & Hex($vElement) Case 'Bool' ; True or False $sName &= ($vElement = True) ? 't' : 'v' Case 'Binary' $sName &= 'y' & $vElement Case 'Ptr' $sName &= 'p' & $vElement Case 'Keyword' ; Default or Null (other variable declarations are illegal) $sName &= ($vElement = Default) ? 'w' : 'n' Case 'Function', 'UserFunction' ; string conversion will fail For $k = 1 To $aFunction[0] ; unique functions are stored in a separate array If $vElement = $aFunction[$k] Then ; this function has been encountered previously $sName &= 'u' & $k ContinueLoop 2 EndIf Next $aFunction[0] += 1 If $aFunction[0] > UBound($aFunction) - 1 Then ReDim $aFunction[$aFunction[0] + 10] $aFunction[$aFunction[0]] = $vElement $sName &= 'u' & $aFunction[0] Case Else ; Array, Object, DLLStruct [or Map] $sName = False ; set to ignore ExitLoop 9 EndSwitch Next Next Next Next Next Next Next Next Next If $sName Then If $oDictionary.Exists($sName) Then ContinueLoop ; this region has been seen previously $oDictionary.Item($sName) ; use $sName as key EndIf ; overwrite the next region (assumes that the first duplicate region will be found quite quickly) If $iDim = 1 Then $aArray[$iItems] = $aArray[$iFrom] Else $fnFloodFill($aArray, $aBound, $iDimension, $iItems, $iFrom, '', $sTransfer) ; access the remote loop region EndIf $iItems += 1 Next $aBound[0] = $iDim ; reset the number of dimensions For $i = 1 To $aBound[0] ; reset the bounds $aBound[$i] += 1 Next $aBound[$iDimension] = $iItems ; new bounds of the explicit dimension __ResetBounds($aArray, $aBound) ; remove the remaining duplicate array regions EndFunc ;==>_ArrayUniqueXD ; #FUNCTION# =================================================================================================================== ; Name...........: _DeleteDimension ; Description ...: Delete dimensions, or a range of dimensions, from a multidimensional array. ; Syntax.........: _DeleteDimension(ByRef $aArray, $iDimension, $iRange = 1) ; Parameters.....; $aArray - [ByRef] The array from which dimensions are deleted. ; $iDimension - Integer value - the dimension (or the first dimension) to delete. ; $iRange - [Optional] Integer value - the number of dimensions to delete. Default = 1 ; Return values .: Success - Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 $aArray is not a valid array. ; |@error = 2 Dimension limit exceeded. ; |@error = 3 Arrays must contain at least one element. ; |@error = 4 Meaningless range value [range must be greater than zero]. ; |@error = 5 Illegal operation - deleting all dimensions is not supported. ; Author ........: czardas ; Comments ......; Beware - deleting dimensions can have very destructive effect on the array's contents. ; Deletes all regions with indices greater than zero while removing each dimension. ; This function will not delete all the dimensions from an array. ; This function is limited to arrays of up to nine dimensions. ; ============================================================================================================================== Func _DeleteDimension(ByRef $aArray, $iDimension, $iRange = 1) If Not IsArray($aArray) Then Return SetError(1) ; this parameter must be an array Local $aBound = __GetBounds($aArray) If @error Then Return SetError(3) ; arrays must contain at least one element If $aBound[0] > 9 Then Return SetError(2) $iDimension = Int($iDimension) If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(2) ; check for dimension range overflow and set to ignore [subject to review] $iRange = ($iRange = Default) ? 1 : Int($iRange) If $iRange < 1 Then Return SetError(4) ; range must be greater than zero If $iDimension + $iRange - 1 >= $aBound[0] Then $iRange = 1 + $aBound[0] - $iDimension If $iRange = $aBound[0] Then Return SetError(5) ; illegal operation [deleting all dimensions is not an intended feature] Local $sTransfer = '$aSource', $iCount = 1, $aBoundNew[$aBound[0] - $iRange + 1] $aBoundNew[0] = $aBound[0] - $iRange For $i = 1 To $aBound[0] If $i < $iDimension Or $i > $iDimension + $iRange - 1 Then ; dimensions to keep $aBoundNew[$iCount] = $aBound[$i] ; assign the bounds of the new array $sTransfer &= '[$a[' & $iCount & ']]' $iCount += 1 Else ; dimensions to delete For $i = $iDimension To $iDimension + $iRange - 1 ; run through the range $sTransfer &= '[0]' ; delete / hide dimensions from the fill instructions Next $i -= 1 ; prevents incrementing the loop iteration count twice EndIf Next Local $aNewArray = ___NewArray($aBoundNew) For $i = 1 To $aBoundNew[0] $aBoundNew[$i] -= 1 ; maximum sub-index within each dimension Next Local $aFloodFill = __FloodFunc() $aFloodFill[$aBoundNew[0]]($aNewArray, $aBoundNew, 0, 0, '', $aArray, $sTransfer) ; flood the new array $aArray = $aNewArray EndFunc ;==>_DeleteDimension ; #FUNCTION# =================================================================================================================== ; Name...........: _DeleteRegion ; Description ...: Deletes a region from a multidimensional array. ; Syntax.........: _DeleteRegion($aArray, $iDimension [, $iSubIndex = 0 [, $iRange = 1]]) ; Parameters.....; $aArray - [ByRef] The array to delete the region from. ; $iDimension - [Optional] Integer value - the dimension used to define the region. Default = 1 ; $iSubIndex - [Optional] Integer value - the index, or start of, of the region to delete. Default = 0 ; $iRange - [Optional] Integer value - the size of the region to delete. Default = 1 ; Return values .: Success - Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 $aArray is not a valid array. ; |@error = 2 Dimension limit exceeded. ; |@error = 3 Dimension does not exist in the array. ; |@error = 4 Arrays must contain at least one element. ; |@error = 5 Sub-index does not exist in the dimension. ; |@error = 6 Invalid Range. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; ============================================================================================================================== Func _DeleteRegion(ByRef $aArray, $iDimension = 1, $iSubIndex = 0, $iRange = 1) If Not IsArray($aArray) Then Return SetError(1) Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension If @error Then Return SetError(4) ; $aArray must contain at least one element If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; out of bounds dimension $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex) If $iSubIndex < 0 Or $iSubIndex > $aBound[$iDimension] - 1 Then Return SetError(5) ; sub-index does not exist in the dimension $iRange = ($iRange = Default) ? 1 : Int($iRange) If $iRange < 1 Then Return SetError(6) ; range must be greater than zero $iRange = ($iSubIndex + $iRange < $aBound[$iDimension]) ? $iRange : $aBound[$iDimension] - $iSubIndex ; corrects for overflow If $iRange = $aBound[$iDimension] Then Return SetError(6) ; deleting the whole region is not currently supported [give reason] $aBound[$iDimension] -= $iRange ; the size of the dimension in the new array If $aBound[0] = 1 Then For $iNext = $iSubIndex To $aBound[$iDimension] - 1 $aArray[$iNext] = $aArray[$iNext + $iRange] Next ReDim $aArray[$aBound[$iDimension]] Return EndIf Local $iMaxIndex = $aBound[$iDimension] - 1 For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next $aBound[$iDimension] = 0 ; set to loop once [one region at a time] Local $iFrom, $sTransfer = '$aTarget' & __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]] For $iNext = $iSubIndex To $iMaxIndex $iFrom = $iNext + $iRange $fnFloodFill($aArray, $aBound, $iDimension, $iNext, $iFrom, '', $sTransfer) ; overwrite the final [untouched] region Next $aBound[$iDimension] = $iMaxIndex For $i = 1 To $aBound[0] $aBound[$i] += 1 Next __ResetBounds($aArray, $aBound) ; delete remaining indices EndFunc ;==>_DeleteRegion ; #FUNCTION# =================================================================================================================== ; Name...........: _ExtractRegion ; Description ...: Extracts a region from a multidimensional array. ; Syntax.........: _ExtractRegion($aArray, $iDimension [, $iSubIndex = 0 [, $iRange = 1]]) ; Parameters.....; $aArray - The array from which to extract the region. ; $iDimension - Integer value - the dimension used to define the region. ; $iSubIndex - [Optional] Integer value - the index, or start of, of the region to extract. Default = 0 ; $iRange - [Optional] Integer value - the number of regions to extract. Default = 1 ; Return values .: Success - Returns a new array containing all the extracted regions within the defined range. ; Failure sets @error as follows: ; |@error = 1 $aArray is not a valid array. ; |@error = 2 Dimension limit exceeded. ; |@error = 3 Dimension does not exist in the array. ; |@error = 4 Arrays must contain at least one element. ; |@error = 5 Sub-index does not exist in the dimension. ; |range must be greater than zero ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; The extracted region will contain the same number of dimensions as the original array. ; ============================================================================================================================== Func _ExtractRegion($aArray, $iDimension, $iSubIndex = 0, $iRange = 1) If Not IsArray($aArray) Then Return SetError(1) Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension If @error Then Return SetError(4) ; $aArray must contain at least one element If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit $iDimension = Int($iDimension) If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; out of bounds dimension $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex) If $iSubIndex < 0 Or $iSubIndex > $aBound[$iDimension] - 1 Then Return SetError(5) ; sub-index does not exist in the dimension $iRange = ($iRange = Default) ? 1 : Int($iRange) If $iRange < 1 Then Return SetError(6) ; range must be greater than zero $iRange = ($iSubIndex + $iRange < $aBound[$iDimension]) ? $iRange : $aBound[$iDimension] - $iSubIndex $aBound[$iDimension] = $iRange ; the size of the dimension in the new array Local $aRegion = ___NewArray($aBound) ; create new array For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next If $aBound[0] = 1 Then For $iNext = 0 To $iRange - 1 $aRegion[$iNext] = $aArray[$iNext + $iSubIndex] Next Return $aRegion EndIf $aBound[$iDimension] = 0 ; set to loop once [one region at a time] Local $iFrom, $sTransfer = '$aSource' & __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]] For $iNext = 0 To $iRange - 1 $iFrom = $iNext + $iSubIndex $fnFloodFill($aRegion, $aBound, $iDimension, $iNext, $iFrom, $aArray, $sTransfer) ; extract region Next Return $aRegion EndFunc ;==>_ExtractRegion ; #FUNCTION# =================================================================================================================== ; Name...........: _InsertRegion ; Description ...: Inserts a multidimensional array into another multidimensional array. ; Syntax.........: _InsertRegion($aTarget, $aSource [, $iDimension = 1 [, $iSubIndex = 0]]) ; Parameters.....; $aTarget - The array to modify. ; $aSource - The array to insert. ; $iDimension - Integer value - the dimension in which insertion takes place. ; $iSubIndex - [Optional] Integer value - sub-index within the dimension where insertion occurs. Default = 0 ; Return values .: Success - Returns the target array ByRef. ; Failure sets @error as follows: ; |@error = 1 $aTarget is not a valid array. ; |@error = 2 $aSource is not a valid array. ; |@error = 3 Arrays must contain at least one element. ; |@error = 4 Array bounds do not match. ; |@error = 5 Output array size exceeds AutoIt limits. ; |@error = 6 $iSubIndex is out of range. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; The target array must contain the same number of dimensions as the source array. ; With the exception of $iDimension; the bounds of all other dimensions, in both arrays, must match. ; ============================================================================================================================== Func _InsertRegion(ByRef $aTarget, $aSource, $iDimension = 1, $iSubIndex = 0) If Not IsArray($aTarget) Or UBound($aTarget, 0) > 9 Then Return SetError(1) If Not IsArray($aSource) Or UBound($aSource, 0) > 9 Then Return SetError(2) Local $aBoundTgt = __GetBounds($aTarget) If @error Then Return SetError(3) ; arrays must contain at least one element Local $aBoundSrc = __GetBounds($aSource) If @error Then Return SetError(3) ; arrays must contain at least one element $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) For $i = 1 To $aBoundTgt[0] If $aBoundTgt[$i] <> $aBoundSrc[$i] And $iDimension <> $i Then Return SetError(4) ; array bounds are inconsistent Next $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex) If $iSubIndex < 0 Or $iSubIndex > $aBoundTgt[$iDimension] Then Return SetError(5) ; $iSubIndex is out of range Switch $iSubIndex Case 0 _ArrayAttach($aSource, $aTarget, $iDimension) If @error Then Return SetError(6) ; output array size exceeds AutoIt limits $aTarget = $aSource Case $aBoundTgt[$iDimension] _ArrayAttach($aTarget, $aSource, $iDimension) If @error Then Return SetError(6) ; output array size exceeds AutoIt limits Case Else ; check output bounds remain within range before modifications begin $aBoundSrc[$iDimension] += $aBoundTgt[$iDimension] Local $iCount = 1 For $i = 1 To $aBoundSrc[0] $iCount *= $aBoundSrc[$i] If $iCount > 16777216 Then Return SetError(6) ; output array size exceeds AutoIt limits Next Local $aEnd = _ExtractRegion($aTarget, $iDimension, $iSubIndex, 16777216) ; out of bounds range values extract all remaining sub-indices within the dimension If @error Then Return SetError(@error) $aBoundTgt[$iDimension] = $iSubIndex __ResetBounds($aTarget, $aBoundTgt) _ArrayAttach($aTarget, $aSource, $iDimension) _ArrayAttach($aTarget, $aEnd, $iDimension) EndSwitch EndFunc ;==>_InsertRegion ; #FUNCTION# =================================================================================================================== ; Name...........: _PreDim ; Description ...: Changes the size of an array by adding, or removing, dimensions. ; Syntax.........: _PreDim($aArray, $iDimensions [, $iPush = False]) ; Parameters.....; $aArray - The original array. ; $iDimensions - The number of dimensions in the returned array. ; $bPush - [Optional] If set to True, new dimensions are created on, or removed from, the left [see comments]. ; Return values .: Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 The first parameter is not an array. ; |@error = 2 The requested array has more than 9 dimensions. ; |@error = 3 The original array has more than 9 dimensions. ; |@error = 4 Arrays must contain at least one element. ; Author.........: czardas ; Comments ......; This function works for up to 9 dimensions. ; By default, new dimensions are added to the right in a standard sequence: $aArray[7][6] ==> $aArray[7][6][1] ; Dimensions are removed in reverse sequence: $aArray[7][6] ==> $aArray[7] ; When the $bPush parameter is set to True, the original array will be pushed to higher dimensions: ; $aArray[7][6] ==> $aArray[1][7][6], or the process reversed: $aArray[7][6] ==> $aArray[6] ; ============================================================================================================================== Func _PreDim(ByRef $aArray, $iDimensions, $bPush = False) If Not IsArray($aArray) Then Return SetError(1) $iDimensions = Int($iDimensions) If $iDimensions < 1 Or $iDimensions > 9 Then Return SetError(2) Local $iPreDims = UBound($aArray, 0) ; current number of dimensions If $iPreDims = $iDimensions Then Return ; no change If $iPreDims > 9 Then Return SetError(3) ; too many dimensions Local $aBound = __GetBounds($aArray) ; get the size of each original dimension If @error Then Return SetError(4) ; $aArray must contain at least one element $aBound[0] = $iDimensions ; overwrite this value with the new number of dimensions Local $sTransfer = '[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]][$a[9]]' ; array syntax to be sent to the remote loop region If $bPush Then ; prefix dimensions, or delete from the left Local $iOffset = Abs($iDimensions - $iPreDims) If $iPreDims > $iDimensions Then ; lower dimensions get deleted For $i = 1 To $iDimensions ; shift elements to lower indices $aBound[$i] = $aBound[$i + $iOffset] Next $sTransfer = '$aSource' & StringLeft('[0][0][0][0][0][0][0][0]', $iOffset * 3) & StringLeft($sTransfer, $iDimensions * 7) Else ; lower dimensions are created ReDim $aBound[$iDimensions + 1] ; make space for more dimensions For $i = $iDimensions To $iOffset + 1 Step -1 ; shift elements to higher indices $aBound[$i] = $aBound[$i - $iOffset] Next For $i = 1 To $iOffset ; assign the size of each additional dimension [1][1][1]... etc... $aBound[$i] = 1 Next $sTransfer = '$aSource' & StringMid($sTransfer, 1 + $iOffset * 7, $iPreDims * 7) EndIf Else ; Default behaviour = append dimensions, or delete from the right ReDim $aBound[$iDimensions + 1] ; modify the number of dimensions [according to the new array] For $i = $iPreDims + 1 To $iDimensions ; assign the size of each new dimension ...[1][1][1] etc... $aBound[$i] = 1 Next $sTransfer = '$aSource' & StringLeft($sTransfer, $iPreDims * 7) EndIf ; add or remove dimensions Local $aNewArray = ___NewArray($aBound) For $i = 1 To $iDimensions $aBound[$i] -= 1 ; convert elements to the maximum index value within each dimension Next ; access the remote loop region Local $iSubIndex = 0, $aFloodFill = __FloodFunc() $aFloodFill[$iDimensions]($aNewArray, $aBound, 0, $iSubIndex, '', $aArray, $sTransfer) $aArray = $aNewArray EndFunc ;==>_PreDim ; #FUNCTION# =================================================================================================================== ; Name...........: _ReverseArray ; Description ...: Reverses regions within a multidimensional array. ; Syntax.........: _ReverseArray($aArray [, $iDimension = 1 [, $iStart = 0 [, $iEnd = -1]]]) ; Parameters.....; $aArray - The array to modify. ; $iDimension - [Optional] Integer value - the dimension in which the array sub-indices (regions) are reversed. ; $iStart - [Optional] The start sub-index within the defined dimension. Default value = 0 ; $iEnd - [Optional] Integer value - The end sub-index within the defined dimension. Default value = -1 ; Return values .: Success - Returns the reversed array [ByRef]. ; Failure sets @error as follows: ; |@error = 1 The 1st parameter is not a valid array. ; |@error = 2 The 1st parameter does not contain any elements. ; |@error = 3 The dimension does not exist. ; |@error = 4 Meaningless $iStart value. ; |@error = 5 Meaningless $iEnd value. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; ============================================================================================================================== Func _ReverseArray(ByRef $aArray, $iDimension = 1, $iStart = 0, $iEnd = -1) If Not IsArray($aArray) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array Local $aBound = __GetBounds($aArray) If @error Then Return SetError(2) ; array contains zero elements $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) ; dimension does not exist $iStart = ($iStart = Default) ? 0 : Int($iStart) If $iStart < 0 Or $iStart > $aBound[$iDimension] - 2 Then Return SetError(4) ; meaningless $iStart value $iEnd = ($iEnd = -1 Or $iEnd = Default) ? $aBound[$iDimension] - 1 : Int($iEnd) If $iEnd <= $iStart Or $iEnd >= $aBound[$iDimension] Then Return SetError(5) ; meaningless $iEnd value If $aBound[0] = 1 Then ___Reverse1D($aArray, $iStart, $iEnd) Else $aBound[$iDimension] = 1 Local $aRegion = ___NewArray($aBound) ; to store extracted regions For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next Local $sIndices = __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]], _ $sTransfer = '$aSource' & $sIndices ; array syntax While $iEnd > $iStart $fnFloodFill($aRegion, $aBound, $iDimension, 0, $iStart, $aArray, $sTransfer) ; extract the current start region $sTransfer = '$aTarget' & $sIndices $fnFloodFill($aArray, $aBound, $iDimension, $iStart, $iEnd, '', $sTransfer) ; overwrite the current start region $sTransfer = '$aSource' & $sIndices $fnFloodFill($aArray, $aBound, $iDimension, $iEnd, 0, $aRegion, $sTransfer) ; overwrite the current end region $iStart += 1 $iEnd -= 1 WEnd EndIf EndFunc ;==>_ReverseArray ; #FUNCTION# =================================================================================================================== ; Name...........: _SearchArray ; Description ...: Searches through a multidimensional array. ; Syntax.........: _SearchArray($aArray, $vSearchTerm [, $bCaseSense = False [, $iDimension = 1]]) ; Parameters.....; $aArray - [ByRef] Target array to which the source array (or data) will be concatenated. ; $vSearchTerm - The string or data to search for. ; $bCaseSense - [Optional] Boolean value - case sensitive search. Default = False ; $iDimension - [Optional] Integer value - the dimension used to conduct the search. Default = 1st dimension ; $iAlgo - [Optional] Algorithm: 1 = exact match, 2 = find a string, 3 = find a word within text. [Default = 1] ; Return values .: Success - Returns an array of all regions containing the term searched for within the defined dimension. ; Failure sets @error as follows: ; |@error = 1 $aArray is not a valid array. ; |@error = 2 Arrays must contain a minimum of one element. ; |@error = 3 Dimension limit exceeded. ; |@error = 4 Bad algorithm. ; |@error = 5 No matches found. ; Author ........: czardas ; Comments ......; This function is limited to arrays of up to nine dimensions. ; Searching through a 2D array in the first dimension returns an array of all rows containing the search term. ; Searching a 2D array in the second dimension will return an array of all columns containing the search term. ; Searching any array will return an array of regions containing the search term within the defined dimension. ; [$iAlgo = 3] A word may contain any characters. Word boundaries are defined by non-alphanumeric characters. ; May return FP matches if $iAlgo = 3, $vSearchTerm contains '\E' and $aArray contains the code point U+E000. ; ============================================================================================================================== Func _SearchArray($aArray, $vSearchTerm, $bCaseSense = False, $iDimension = 1, $iAlgo = 1) ; [Exact Match] If Not IsArray($aArray) Then Return SetError(1) ; this parameter must be an array Local $aBound = __GetBounds($aArray) If @error Then Return SetError(2) ; arrays must contain at least one element If $aBound[0] > 9 Then Return SetError(3) ; dimension range exceeded $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) $iAlgo = ($iAlgo = Default) ? 1 : Int($iAlgo) If $iAlgo < 1 Or $iAlgo > 3 Then Return SetError(4) If $aBound[0] = 1 Then ; 1D special case $aArray = ___Search1D($aArray, $vSearchTerm, $bCaseSense, $iAlgo) Return @error ? SetError(5) : $aArray EndIf For $i = 1 To $aBound[0] $aBound[$i] -= 1 ; maximum index value within each dimension Next Local $iItems = 0, $iMaxIndex = $aBound[$iDimension], $fnFloodFill = __FloodFunc()[$aBound[0]], $aFunc = ['__FindExact', '__FindString', '__FindWord'], _ $sTransfer = $aFunc[$iAlgo - 1] & ($bCaseSense ? 'Case' : '') & '($aTarget, $a, $aBound, $iFrom, "$aTarget' & _ __HiddenIndices($aBound[0], $iDimension) & '")' ; string to execute $aBound[0] = $vSearchTerm $aBound[$iDimension] = 0 ; this loop must only run once on each encounter For $iFrom = 0 To $iMaxIndex ; loop through sub-indices within the dimension $fnFloodFill($aArray, $aBound, $iDimension, $iItems, $iFrom, '', $sTransfer) ; overwrite the current region while searching If Not $g__ARRWSHOP_RESUME Then ; a match halted the search during the overwrite $iItems += 1 ; set to overwrite the next region $g__ARRWSHOP_RESUME = True ; resume searching on the next pass EndIf Next If $iItems = 0 Then Return SetError(5) ; no matches found $aBound[0] = UBound($aBound) - 1 ; reset all bounds For $i = 1 To $aBound[0] $aBound[$i] += 1 Next $aBound[$iDimension] = $iItems __ResetBounds($aArray, $aBound) ; remove mismatches Return $aArray EndFunc ;==>_SearchArray ; #FUNCTION# =================================================================================================================== ; Name...........: _ShuffleArray ; Description ...: Shuffles multidimensional regions within an array, or items within multidimensional regions. ; Syntax.........: _ShuffleArray($aArray [, $iDimension = 1 [, $bFruitMachineStyle = False]]) ; Parameters.....; $aArray - The original array. ; $iDimension - [Optional] - The dimension used to define the regions to be shuffled. Default = 1 ; $bFruitMachineStyle - [Optional] Shuffle all items within regions defined by the dimension. Default = False ; Return values .: Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 The first parameter is not a valid array. ; |@error = 2 The first parameter contains the wrong number of dimensions. ; |@error = 3 The second parameter does not relate to any of the dimensions available. ; |@error = 4 Arrays must contain at least one element. ; Author.........: czardas ; Comments ......; This function works for arrays of up to 9 dimensions. ; Setting $iDimension = 0 overrides the 3rd parameter and shuffles everything - anywhere within the array. ; Example .......; _ShuffleArray($aArray, 2, True) ; ==> This is a fruit machine! ; ============================================================================================================================== Func _ShuffleArray(ByRef $aArray, $iDimension = 1, $bFruitMachineStyle = False) If Not IsArray($aArray) Then Return SetError(1) Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension If @error Then Return SetError(4) ; $aArray must contain at least one element If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension > $aBound[0] Or $iDimension < 0 Then Return SetError(3) ; out of bounds dimension Local $aTemp = $aBound ; regional bounds For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next Local $iSubIndex, $sTransfer, $aFloodFill = __FloodFunc() If $iDimension > 0 Then ; shuffle regions or elements within regions If $aBound[0] > 1 Then $aTemp[$iDimension] = 1 Local $aRegion = ___NewArray($aTemp) ; to store extracted regions Local $sIndices = __HiddenIndices($aBound[0], $iDimension) $aTemp = $aBound $aTemp[$iDimension] = 0 ; set to loop once [one region at a time] If $bFruitMachineStyle Then ; contents will be shuffled within each region $sTransfer = '$aSource' & $sIndices ; array syntax For $iSubIndex = 0 To $aBound[$iDimension] ; loop through all indices within the dimension $aFloodFill[$aBound[0]]($aRegion, $aTemp, $iDimension, 0, $iSubIndex, $aArray, $sTransfer) ; extract region __ShuffleXD($aRegion, $aTemp) ; shuffle the extracted region $aFloodFill[$aBound[0]]($aArray, $aTemp, $iDimension, $iSubIndex, 0, $aRegion, $sTransfer) ; reinsert the shuffled region Next Else ; regions will be shuffled within the dimension Local $iRandom $sTransfer = '$aSource' & $sIndices For $iSubIndex = 0 To $aBound[$iDimension] $aFloodFill[$aBound[0]]($aRegion, $aTemp, $iDimension, 0, $iSubIndex, $aArray, $sTransfer) ; extract each region $sTransfer = '$aTarget' & $sIndices $iRandom = Random(0, $aBound[$iDimension], 1) ; acquire a random index $aFloodFill[$aBound[0]]($aArray, $aTemp, $iDimension, $iSubIndex, $iRandom, $aArray, $sTransfer) ; replace the original region $sTransfer = '$aSource' & $sIndices $aFloodFill[$aBound[0]]($aArray, $aTemp, $iDimension, $iRandom, 0, $aRegion, $sTransfer) ; replace the extracted region at the acquired index Next EndIf Else ; not a multidimensional array __Shuffle1D($aArray) ; shuffle the contents EndIf Else ; totally random - ignoring dimension bounds __ShuffleXD($aArray, $aBound) EndIf EndFunc ;==>_ShuffleArray #Region - Miscellaneous ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with numeric sort. Decimal strings should first be formatted with ___FormatNum() ; Author ........: czardas ; ============================================================================================================================== Func ___AcquireExponent($vNum) Local $bString = IsString($vNum) If $bString Then $vNum = StringReplace($vNum, '-', '') ; the minus symbol must first be stripped Return $bString ? ((StringLeft($vNum, 1) = '.') ? StringLen(StringRegExpReplace($vNum, '\.0*', '')) - StringLen($vNum) : StringInStr($vNum, '.') - 2) : Number(StringRight(StringFormat('%.1e', $vNum / 1), 4)) EndFunc ;==>___AcquireExponent ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Description ...: Return an array with a range of assigned index values (used to track migration patterns in __QuickSortXD). ; Author ........: czardas ; =============================================================================================================================== Func __CreateTrac($iBound, $iStart, $iEnd) Local $aTracker[$iBound] For $i = $iStart To $iEnd $aTracker[$i] = $i ; fill the (tracking) range with indices Next Return $aTracker EndFunc ;==>__CreateTrac ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Extract a vector (list) from any dimension within a multidimensional array. ; ============================================================================================================================== Func __ExtractVector($aArray, $iDimension, $aIndices) $aIndices[$iDimension] = '$a[1]' ; $aIndices[$iDimension] is the remote loop count Local $sTransfer = '$aSource' ; the main array is the source For $i = 1 To $aIndices[0] $sTransfer &= '[' & $aIndices[$i] & ']' Next Local $iBound = UBound($aArray, $iDimension), $aVector[$iBound], $iSubIndex = 0, $aBound = ['', $iBound - 1] ___Flood1D($aVector, $aBound, $iDimension, $iSubIndex, '', $aArray, $sTransfer) Return $aVector EndFunc ;==>__ExtractVector ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - non-case-sensitive comparison. ; ============================================================================================================================== Func __FindExact($aTarget, $a, $aBound, $iFrom, $sSyntax) ; [default algorithm] $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And $aBound[0] = $sSyntax Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindExact ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - case-sensitive comparison. ; ============================================================================================================================== Func __FindExactCase($aTarget, $a, $aBound, $iFrom, $sSyntax) $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And $aBound[0] == $sSyntax Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindExactCase ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - search within strings - non-case-sensitive comparison. ; ============================================================================================================================== Func __FindString($aTarget, $a, $aBound, $iFrom, $sSyntax) $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And StringInStr($sSyntax, $aBound[0]) Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindString ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - search within strings - case-sensitive comparison. ; ============================================================================================================================== Func __FindStringCase($aTarget, $a, $aBound, $iFrom, $sSyntax) $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And StringInStr($sSyntax, $aBound[0], 1) Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindStringCase ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - search between word boundaries - non-case-sensitive comparison. ; ============================================================================================================================== Func __FindWord($aTarget, $a, $aBound, $iFrom, $sSyntax) $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And StringRegExp(StringReplace($sSyntax, '\E', $g__ARRWSHOP_SUB, 0, 1), '(*UCP)(?i)(\A|[^[:alnum:]])(\Q' & StringReplace($aBound[0], '\E', $g__ARRWSHOP_SUB, 0, 1) & '\E)(\z|[^[:alnum:]])') Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindWord ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - search between word boundaries - case-sensitive comparison. ; ============================================================================================================================== Func __FindWordCase($aTarget, $a, $aBound, $iFrom, $sSyntax) $sSyntax = Execute($sSyntax) If $g__ARRWSHOP_RESUME And StringRegExp(StringReplace($sSyntax, '\E', $g__ARRWSHOP_SUB, 0, 1), '(*UCP)(\A|[^[:alnum:]])(\Q' & StringReplace($aBound[0], '\E', $g__ARRWSHOP_SUB, 0, 1) & '\E)(\z|[^[:alnum:]])') Then $g__ARRWSHOP_RESUME = False Return $sSyntax #forceref $aTarget, $a, $iFrom EndFunc ;==>__FindWordCase ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Return an array of functions used for populating multidimensional array elements. ; ============================================================================================================================== Func __FloodFunc() Local $aFloodFunc = ['', ___Flood1D, ___Flood2D, ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D] Return $aFloodFunc EndFunc ;==>__FloodFunc ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with numeric sort. ['\A[\+\-]?(\d*\.?\d+|d+\.)\z' only ==> 1.0 .01 0.] ; Author ........: czardas ; ============================================================================================================================== Func ___FormatNum($sNum) If Not StringRegExp($sNum, '[1-9]') Then Return 0 $sNum = StringReplace($sNum, '+', '') ; get rid of plus symbol $sNum = StringRegExpReplace($sNum, "^-?\K(?=\.)", "0") ; add zeros [courtesy of jguinch] $sNum = StringRegExpReplace($sNum, "^-?\K0+(?=[1-9]|0\.?)|\.0*$|\.\d*[1-9]\K0+", "") ; strip zeros [courtesy of jguinch] If Execute($sNum) == $sNum Then Return Execute($sNum) ; return a number Return StringInStr($sNum, '.') ? StringRegExpReplace($sNum, '(\A\-?)(0)', '\1') : $sNum & '.' ; for fast comparison with floats [^^ StringCompare('1.', 1) > 0] EndFunc ;==>___FormatNum ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Get the bounds of each available dimension in a multidimensional array. ; ============================================================================================================================== Func __GetBounds($aArray, $iHypothetical = 0) Local $iMaxDim = UBound($aArray, 0) Local $aBound[($iHypothetical ? $iHypothetical : $iMaxDim) + 1] ; [or ==> Local $aBound[9]] $aBound[0] = $iMaxDim For $i = 1 To $iMaxDim $aBound[$i] = UBound($aArray, $i) If $aBound[$i] = 0 Then Return SetError(1) Next If $iHypothetical Then For $i = $iMaxDim + 1 To $iHypothetical $aBound[$i] = 1 ; imaginary dimensions Next EndIf Return $aBound EndFunc ;==>__GetBounds ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Return a fragment of code which is the format for the $sTransfer parameter in ___FloodXD. ; ============================================================================================================================== Func __HiddenIndices($iBound, $iDimension) Local $sSyntax = '' ; to access elements at their original indices For $i = 1 To $iBound If $i <> $iDimension Then $sSyntax &= '[$a[' & $i & ']]' ; default ==> '$aSource[$iFrom][$a[2]][$a[3]][$a[4]][$a[5]] etc...' Else $sSyntax &= '[$iFrom]' EndIf Next Return $sSyntax EndFunc ;==>__HiddenIndices ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Create an array of between one and nine dimensions using predefined bounds. ; ============================================================================================================================== Func ___NewArray($aBound) Switch $aBound[0] Case 1 Local $aArray[$aBound[1]] Case 2 Local $aArray[$aBound[1]][$aBound[2]] Case 3 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]] Case 4 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]] Case 5 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]] Case 6 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]] Case 7 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]] Case 8 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]] Case 9 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]] EndSwitch Return $aArray EndFunc ;==>___NewArray ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _SortArray() numeric comparison [str > num(?), num > str(?), str > str(?)] ; Author ........: czardas ; ============================================================================================================================== Func ___NumCompare($vNum1, $vNum2) ; ($vNum1 > $vNum2) If IsNumber($vNum1) And IsNumber($vNum2) Then If $vNum1 = $vNum2 Then Return 0 Return ($vNum1 > $vNum2) ? 1 : -1 EndIf If $vNum1 == '1.#INF' Or $vNum2 == '-1.#INF' Then Return 1 ; these values interfere with the comparison below If $vNum1 == '-1.#INF' Or $vNum2 == '1.#INF' Then Return -1 ; ditto Local $bNeg1 = (StringLeft($vNum1, 1) = '-') If $bNeg1 <> (StringLeft($vNum2, 1) = '-') Then Return $bNeg1 ? -1 : 1 Local $iExp1 = ___AcquireExponent($vNum1), $iExp2 = ___AcquireExponent($vNum2) If $iExp1 <> $iExp2 Then Return (($iExp1 > $iExp2) ? 1 : -1) * ($bNeg1 ? -1 : 1) ; negative magnitude changes the result Local $bType1 = (VarGetType($vNum1) = 'Double'), $bType2 = (VarGetType($vNum2) = 'Double') If $bType1 Or $bType2 Then ; grab all 17 digits from the double $vNum1 = $bType1 ? StringLeft(StringReplace(StringFormat('%.17e', $vNum1), '.', ''), 17) : StringReplace($vNum1, '.', '') $vNum2 = $bType2 ? StringLeft(StringReplace(StringFormat('%.17e', $vNum2), '.', ''), 17) : StringReplace($vNum2, '.', '') EndIf Return StringCompare($vNum1, $vNum2) * ($bNeg1 ? -1 : 1) ; negative magnitude changes the result EndFunc ;==>___NumCompare ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __QuickSort1D [adaptation of __ArrayQuickSort1D] ; Description ...: Helper function for sorting 1D arrays ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: czardas - replaced alphanumeric sort with separate lexical and numeric sorting algorithms. ; =============================================================================================================================== Func __QuickSort1D(ByRef $aArray, $iStart, $iEnd, $iAlgorithm = 0) If $iEnd <= $iStart Then Return Local $vTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Switch $iAlgorithm Case 0 ; lexical For $i = $iStart + 1 To $iEnd $vTmp = $aArray[$i] For $j = $i - 1 To $iStart Step -1 If StringCompare($vTmp, $aArray[$j]) >= 0 Then ExitLoop $aArray[$j + 1] = $aArray[$j] Next $aArray[$j + 1] = $vTmp Next Return Case 2 ; numeric strict For $i = $iStart + 1 To $iEnd $vTmp = $aArray[$i] If IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 If $vTmp >= $aArray[$j] And IsNumber($aArray[$j]) Then ExitLoop $aArray[$j + 1] = $aArray[$j] Next $aArray[$j + 1] = $vTmp EndIf Next Return EndSwitch Return EndIf ; QuickSort Local $L = $iStart, $R = $iEnd, $vPivot = $aArray[Int(($iStart + $iEnd) / 2)] Do If $iAlgorithm = 0 Then ; lexical While StringCompare($aArray[$L], $vPivot) < 0 $L += 1 WEnd While StringCompare($aArray[$R], $vPivot) > 0 $R -= 1 WEnd ElseIf $iAlgorithm = 2 Then ; numeric strict While $aArray[$L] < $vPivot $L += 1 WEnd While $aArray[$R] > $vPivot $R -= 1 WEnd EndIf If $L <= $R Then ; Swap $vTmp = $aArray[$L] $aArray[$L] = $aArray[$R] $aArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R __QuickSort1D($aArray, $iStart, $R, $iAlgorithm) __QuickSort1D($aArray, $L, $iEnd, $iAlgorithm) EndFunc ;==>__QuickSort1D ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __QuickSortXD [adaptation of __ArrayQuickSort1D] ; Description ...: Helper function for sorting multidimensional arrays ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: czardas - to sort indices of an X-dimensional array vector, instead of overwriting complete regions or rows. ; =============================================================================================================================== Func __QuickSortXD($aArray, ByRef $aTrac, $iStart, $iEnd, $iAlgorithm = 0) If $iEnd <= $iStart Then Return Local $iTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Switch $iAlgorithm Case 0 ; lexical For $i = $iStart + 1 To $iEnd $iTmp = $aTrac[$i] For $j = $i - 1 To $iStart Step -1 If (StringCompare($aArray[$iTmp], $aArray[$aTrac[$j]]) >= 0) Then ExitLoop $aTrac[$j + 1] = $aTrac[$j] Next $aTrac[$j + 1] = $iTmp Next Case 2 ; (or 4) numeric strict [also applies to algorithm 4] For $i = $iStart + 1 To $iEnd $iTmp = $aTrac[$i] For $j = $i - 1 To $iStart Step -1 If $aArray[$iTmp] >= $aArray[$aTrac[$j]] Then ExitLoop $aTrac[$j + 1] = $aTrac[$j] Next $aTrac[$j + 1] = $iTmp Next Case 256 ; numeric [preprocessed; decimal string formatting required, see ___FormatNum] For $i = $iStart + 1 To $iEnd $iTmp = $aTrac[$i] For $j = $i - 1 To $iStart Step -1 If ___NumCompare($aArray[$iTmp], $aArray[$aTrac[$j]]) >= 0 Then ExitLoop $aTrac[$j + 1] = $aTrac[$j] Next $aTrac[$j + 1] = $iTmp Next EndSwitch Return EndIf ; QuickSort Local $L = $iStart, $R = $iEnd, $vPivot = $aArray[$aTrac[Int(($iStart + $iEnd) / 2)]] Do If $iAlgorithm = 0 Then ; lexical While StringCompare($aArray[$aTrac[$L]], $vPivot) < 0 $L += 1 WEnd While StringCompare($aArray[$aTrac[$R]], $vPivot) > 0 $R -= 1 WEnd ElseIf $iAlgorithm = 2 Then ; numeric strict [strings not allowed] While $aArray[$aTrac[$L]] < $vPivot $L += 1 WEnd While $aArray[$aTrac[$R]] > $vPivot $R -= 1 WEnd ElseIf $iAlgorithm = 256 Then ; numeric greedy [includes decimal strings] While ___NumCompare($aArray[$aTrac[$L]], $vPivot) < 0 $L += 1 WEnd While ___NumCompare($aArray[$aTrac[$R]], $vPivot) > 0 $R -= 1 WEnd EndIf If $L <= $R Then ; Swap $iTmp = $aTrac[$L] $aTrac[$L] = $aTrac[$R] $aTrac[$R] = $iTmp $L += 1 $R -= 1 EndIf Until $L > $R __QuickSortXD($aArray, $aTrac, $iStart, $R, $iAlgorithm) __QuickSortXD($aArray, $aTrac, $L, $iEnd, $iAlgorithm) EndFunc ;==>__QuickSortXD ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: ReDim arrays of different dimensions. ; ============================================================================================================================== Func __ResetBounds(ByRef $aArray, $aBound) Switch $aBound[0] Case 1 ReDim $aArray[$aBound[1]] Case 2 ReDim $aArray[$aBound[1]][$aBound[2]] Case 3 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]] Case 4 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]] Case 5 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]] Case 6 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]] Case 7 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]] Case 8 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]] Case 9 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]] EndSwitch EndFunc ;==>__ResetBounds ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Description ...: Helper function: reverses a 1D array. ; Author ........: czardas ; =============================================================================================================================== Func ___Reverse1D(ByRef $aArray, $iStart, $iStop) Local $vTemp While $iStop > $iStart $vTemp = $aArray[$iStart] $aArray[$iStart] = $aArray[$iStop] $aArray[$iStop] = $vTemp $iStart += 1 $iStop -= 1 WEnd EndFunc ;==>___Reverse1D ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with _ArraySearch - searches through a 1D array. ; ============================================================================================================================== Func ___Search1D($aArray, $vSearchTerm, $bCaseSense, $iAlgo) Local $iItems = 0 Switch $iAlgo Case 1 ; find exact match If $bCaseSense Then ; case-sensitive For $i = 0 To UBound($aArray) - 1 If $aArray[$i] == $vSearchTerm Then $aArray[$iItems] = $aArray[$i] $iItems += 1 EndIf Next Else ; optimal [using a second loop avoids using a conditional within the loop] For $i = 0 To UBound($aArray) - 1 If $aArray[$i] = $vSearchTerm Then $aArray[$iItems] = $aArray[$i] $iItems += 1 EndIf Next EndIf Case 2 ; find a string within a string For $i = 0 To UBound($aArray) - 1 If StringInStr($aArray[$i], $vSearchTerm, $bCaseSense) Then $aArray[$iItems] = $aArray[$i] $iItems += 1 EndIf Next Case 3 ; find a word within text Local $sPattern = $bCaseSense ? '(*UCP)(\A|[^[:alnum:]])(\Q' : '(*UCP)(?i)(\A|[^[:alnum:]])(\Q' For $i = 0 To UBound($aArray) - 1 If StringRegExp(StringReplace($aArray[$i], '\E', $g__ARRWSHOP_SUB, 0, 1), $sPattern & StringReplace($vSearchTerm, '\E', $g__ARRWSHOP_SUB, 0, 1) & '\E)(\z|[^[:alnum:]])') Then $aArray[$iItems] = $aArray[$i] $iItems += 1 EndIf Next EndSwitch If Not $iItems Then Return SetError(1) ReDim $aArray[$iItems] Return $aArray EndFunc ;==>___Search1D ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with numeric sort. [numbers other than -1.#IND = OK] ; ============================================================================================================================== Func __Separate1D(ByRef $aArray, $iStart, $iEnd) Local $vTemp, $iItems = 0 For $i = $iStart To $iEnd If IsNumber($aArray[$i]) And Not ($aArray[$i] == '-1.#IND') Then $vTemp = $aArray[$iStart + $iItems] $aArray[$iStart + $iItems] = $aArray[$i] $aArray[$i] = $vTemp $iItems += 1 EndIf Next Return $iItems ; the number of numeric items EndFunc ;==>__Separate1D ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with numeric sort - separates numbers from strings. [numbers (!-1.#IND) = OK, decimal strings = OK] ; Author ........: czardas ; ============================================================================================================================== Func __Separate256(ByRef $aArray, ByRef $aTrac, $iStart, $iEnd) Local $vTemp, $iItems = 0 For $i = $iStart To $iEnd If (IsNumber($aArray[$aTrac[$i]]) And Not ($aArray[$aTrac[$i]] == '-1.#IND')) Or IsString($aArray[$aTrac[$i]]) * StringRegExp($aArray[$aTrac[$i]], '\A\h*[\+\-]?\h*(\d*\.?\d+|\d+\.)\h*\z') Then $vTemp = $aTrac[$iStart + $iItems] $aTrac[$iStart + $iItems] = $aTrac[$i] $aTrac[$i] = $vTemp If IsString($aArray[$aTrac[$iStart + $iItems]]) Then $aArray[$aTrac[$iStart + $iItems]] = ___FormatNum(StringStripWS($aArray[$aTrac[$iStart + $iItems]], 8)) ; format numeric strings ready for comparison $iItems += 1 EndIf Next Return $iItems ; the number of numeric items EndFunc ;==>__Separate256 ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: For use with numeric sort - separates numbers from strings. [numbers (! -1.#IND) = OK] ; Author ........: czardas ; ============================================================================================================================== Func __SeparateXD(ByRef $aArray, ByRef $aTrac, $iStart, $iEnd) Local $vTemp, $iItems = 0 For $i = $iStart To $iEnd If IsNumber($aArray[$aTrac[$i]]) And Not ($aArray[$aTrac[$i]] == '-1.#IND') Then $vTemp = $aTrac[$iStart + $iItems] $aTrac[$iStart + $iItems] = $aTrac[$i] $aTrac[$i] = $vTemp $iItems += 1 EndIf Next Return $iItems ; the number of numeric items EndFunc ;==>__SeparateXD ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Shuffle a one dimensional array. ; ============================================================================================================================== Func __Shuffle1D(ByRef $aArray) Local $vTemp, $iRandom, $iBound = UBound($aArray) - 1 For $i = 0 To $iBound $iRandom = Random(0, $iBound, 1) $vTemp = $aArray[$i] $aArray[$i] = $aArray[$iRandom] $aArray[$iRandom] = $vTemp Next EndFunc ;==>__Shuffle1D ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Shuffle a multidimensional array. ; ============================================================================================================================== Func __ShuffleXD(ByRef $aArray, $aBound) ReDim $aBound[10] ; [could possibly be dealt with earlier by the call to _GetBounds] Local $vTemp, $R[10] ; [random indices] For $9 = 0 To $aBound[9] For $8 = 0 To $aBound[8] For $7 = 0 To $aBound[7] For $6 = 0 To $aBound[6] For $5 = 0 To $aBound[5] For $4 = 0 To $aBound[4] For $3 = 0 To $aBound[3] For $2 = 0 To $aBound[2] For $1 = 0 To $aBound[1] For $i = 1 To $aBound[0] $R[$i] = Random(0, $aBound[$i], 1) Next Switch $aBound[0] Case 1 $vTemp = $aArray[$1] $aArray[$1] = $aArray[$R[1]] $aArray[$R[1]] = $vTemp Case 2 $vTemp = $aArray[$1][$2] $aArray[$1][$2] = $aArray[$R[1]][$R[2]] $aArray[$R[1]][$R[2]] = $vTemp Case 3 $vTemp = $aArray[$1][$2][$3] $aArray[$1][$2][$3] = $aArray[$R[1]][$R[2]][$R[3]] $aArray[$R[1]][$R[2]][$R[3]] = $vTemp Case 4 $vTemp = $aArray[$1][$2][$3][$4] $aArray[$1][$2][$3][$4] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]] = $vTemp Case 5 $vTemp = $aArray[$1][$2][$3][$4][$5] $aArray[$1][$2][$3][$4][$5] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]] = $vTemp Case 6 $vTemp = $aArray[$1][$2][$3][$4][$5][$6] $aArray[$1][$2][$3][$4][$5][$6] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]] = $vTemp Case 7 $vTemp = $aArray[$1][$2][$3][$4][$5][$6][$7] $aArray[$1][$2][$3][$4][$5][$6][$7] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]] = $vTemp Case 8 $vTemp = $aArray[$1][$2][$3][$4][$5][$6][$7][$8] $aArray[$1][$2][$3][$4][$5][$6][$7][$8] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]][$R[8]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]][$R[8]] = $vTemp Case 9 $vTemp = $aArray[$1][$2][$3][$4][$5][$6][$7][$8][$9] $aArray[$1][$2][$3][$4][$5][$6][$7][$8][$9] = $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]][$R[8]][$R[9]] $aArray[$R[1]][$R[2]][$R[3]][$R[4]][$R[5]][$R[6]][$R[7]][$R[8]][$R[9]] = $vTemp EndSwitch Next Next Next Next Next Next Next Next Next EndFunc ;==>__ShuffleXD ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Description ...: Helper function for populating 1D arrays. [knight's tour type algorithm] ; Author ........: czardas ; =============================================================================================================================== Func __TagSortSwap(ByRef $aArray, ByRef $aTrac, $iStart, $iEnd) Local $vFirst, $i, $iNext For $iInit = $iStart To $iEnd ; initialize each swap sequence If $aTrac[$iInit] <> $iInit Then ; elements will now be swapped in a sequence $i = $iInit ; set the current index to the start of the sequence $vFirst = $aArray[$i] ; copy data [although we don't know where to put it yet] Do $aArray[$i] = $aArray[$aTrac[$i]] ; overwrite each element in the sequence $iNext = $aTrac[$i] ; get the next index in the sequence $aTrac[$i] = $i ; set to ignore overwritten elements on subsequent encounters $i = $iNext ; follow the trail as far as it goes [index could be higher or lower] Until $aTrac[$i] = $iInit ; all sequences end at this juncture $aArray[$i] = $vFirst ; now we know where to put the initial element we copied earlier $aTrac[$i] = $i ; set to ignore on subsequent encounters [as above] EndIf Next EndFunc ;==>__TagSortSwap ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Description ...: Helper function for populating 2D arrays. [knight's tour type algorithm] ; Author ........: czardas ; =============================================================================================================================== Func __TagSortSwapXD(ByRef $aArray, ByRef $aTrac, $iStart, $iEnd) Local $iCols = UBound($aArray, 2), $aFirst[$iCols], $i, $iNext For $iInit = $iStart To $iEnd ; initialize each potential overwrite sequence [separate closed system] If $aTrac[$iInit] <> $iInit Then ; rows will now be overwritten in accordance with tracking information $i = $iInit ; set the current row as the start of the sequence For $j = 0 To $iCols - 1 $aFirst[$j] = $aArray[$i][$j] ; copy the first row [although we don't know where to put it yet] Next Do For $j = 0 To $iCols - 1 $aArray[$i][$j] = $aArray[$aTrac[$i]][$j] ; overwrite each row [following the trail] Next $iNext = $aTrac[$i] ; get the index of the next row in the sequence $aTrac[$i] = $i ; set to ignore rows already processed [may be needed once, or not at all] $i = $iNext ; follow the trail as far as it goes [indices could be higher or lower] Until $aTrac[$i] = $iInit ; all tracking sequences end at this juncture For $j = 0 To $iCols - 1 $aArray[$i][$j] = $aFirst[$j] ; now we know where to put the initial row we copied earlier Next $aTrac[$i] = $i ; set to ignore rows already processed [as above] EndIf Next EndFunc ;==>__TagSortSwapXD #EndRegion - Miscellaneous #Region - Remote Loops ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: ___Flood1D, ___Flood2D, ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D ; Description ...: Flood the region of a multidimensional array defined by the sub-index within the specified dimension. ; Syntax.........: ___FloodXD($aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) ; Parameters.....; $aTarget - Array to populate. ; $aBound - Array containing the bounds of each dimension. ; $iDimension - Integer value defining the dimension. ; $iSubIndex - Integer value of the sub-index within the dimension. ; $iFrom - [Hidden] Integer value defining a sub-index within $aSource. ; $aSource - [Hidden] Array containing data which may be used to populate the target array. ; $sTransfer - String of instructions used to acquire data. ; Return values .: [ByRef] The target array after the region has been flooded. ; Author ........: czardas ; Comments ......; Using remote loops cuts out several hundred lines of duplicated code. ; Recursively targeting a custom function, whichever dimension, is straight forward and reasonably optimal. ; The approach may introduce a small circumstantial speed deficit, which seems a fair trade-off. ; The sequence of loops runs backwards: optimized for higher dimensions with less bounds. ; Only the elements associated with the specified sub-index within the defined dimension are overwritten. ; Setting $iDimension to 0 causes the functions to overwrite all the elements within the target array. ; The $sTransfer parameter must be runnable code. ; Unused hidden parameters should be passed as empty strings. ; $aBound[0] can also be used as a wild card. ; ============================================================================================================================== Func ___Flood1D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) ; [still experimental] #forceref $iDimension, $iFrom, $aSource ; $iDimension would normally not apply here (special case) Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array] For $a[1] = $iSubIndex To $aBound[1] ; from the start to the bounds of the 1st dimension (special case) ; only one operation is needed in this special case $aTarget[$a[1]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed Next EndFunc ;==>___Flood1D ; ============================================================================================================================== ; the following functions are slightly different ; ============================================================================================================================== Func ___Flood2D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource ; hidden parameters Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex ; override the iteration count (fast method) - $a[0] has no influence $aTarget[$a[1]][$a[2]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed Next Next EndFunc ;==>___Flood2D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood3D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource ; as above Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; as above For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex ; as above $aTarget[$a[1]][$a[2]][$a[3]] = Execute($sTransfer) ; as above Next Next Next EndFunc ;==>___Flood3D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood4D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]] = Execute($sTransfer) Next Next Next Next EndFunc ;==>___Flood4D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood5D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[5] = 0 To $aBound[5] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]] = Execute($sTransfer) Next Next Next Next Next EndFunc ;==>___Flood5D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood6D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[6] = 0 To $aBound[6] For $a[5] = 0 To $aBound[5] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]] = Execute($sTransfer) Next Next Next Next Next Next EndFunc ;==>___Flood6D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood7D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[7] = 0 To $aBound[7] For $a[6] = 0 To $aBound[6] For $a[5] = 0 To $aBound[5] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]] = Execute($sTransfer) Next Next Next Next Next Next Next EndFunc ;==>___Flood7D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood8D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[8] = 0 To $aBound[8] For $a[7] = 0 To $aBound[7] For $a[6] = 0 To $aBound[6] For $a[5] = 0 To $aBound[5] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]] = Execute($sTransfer) Next Next Next Next Next Next Next Next EndFunc ;==>___Flood8D ; ============================================================================================================================== ; see previous description and comments ; ============================================================================================================================== Func ___Flood9D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] For $a[9] = 0 To $aBound[9] For $a[8] = 0 To $aBound[8] For $a[7] = 0 To $aBound[7] For $a[6] = 0 To $aBound[6] For $a[5] = 0 To $aBound[5] For $a[4] = 0 To $aBound[4] For $a[3] = 0 To $aBound[3] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex $aTarget[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]][$a[9]] = Execute($sTransfer) Next Next Next Next Next Next Next Next Next EndFunc ;==>___Flood9D #EndRegion - Remote Loops #Au3Stripper_On This UDF and all examples can be downloaded in the zip archive below. ArrayWorkshop.7z Related Topics : https://www.autoitscript.com/forum/topic/179779-_arraydeclarefromstring-_arraytodeclarationstring-_arrayshufflemultidim-_arraycompare-_arrayenumvalues-_arrayassign/ - some rather nice functions. Interesting link from @jchd : https://reference.wolfram.com/language/guide/ListManipulation.html - more stuff than I am ever likely to use.
  24. I import CSV files which have various headers. Is there a way to simply keep only the ones I need and in the order I need them in? For example, if the array's first row's values are Foo Bar Test This, then I want to turn them to Foo This Bar. Here's how I do it "manually" with _ArrayColDelete and _ArraySwap, but I want to use something smarter like rearrange($aArray, ["Foo", "This", "Bar"]): #include <Array.au3> Local $aArray[4][4] = [["Foo", "Bar", "Test", "This"], [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] _ArrayDisplay($aArray, "Original") _ArrayColDelete($aArray, 2) ;2 stands for Test, but next time Test might not be 2, but it will still be called "Test" _ArraySwap($aArray, 1, 2, true) ;1 and 2 might be different next time, but their names will remain _ArrayDisplay($aArray, "Modified") If it helps, I do the same thing in VBA based on Sub Reorganize_columns (the second/alternative example in that page).
  25. Hi all, I was pondering over a question with regards to the speeds of reading something and did not see this kind of question in a forum search. The question: What is (technically) faster? Multiple reads from the same 3d array cell, or only once make a 'temp' variable from that cell and read the value from this? I don't know if either has any real impact at all anyway, but just wanted to ask anyway. :-) There may be a difference if the value holds an integer or a string (or something else) but in my case, is a simple integer. To hopefully clarify with a small bit of code: $process = $start - 15 If $xy[$process][3] <> "x" Then If _ArraySearch($open, $process, 1, $open[0][0], 0, 0, 1, 1) <> -1 Then UpdateOpen($xy[$process][5], $closed[0][0]) ElseIf $start > 0 And _ArraySearch($closed, $process, 1, $closed[0][0], 0, 0, 1, 0) = -1 Then Add_open($start, $closed[0][0], $counter, $process) EndIf EndIf You can read from this, that the array $closed[0][0] is being read 3 times. And this goes on further in the code I did not show. My question boils down to this, should I make a 'temp' variable to hold that $closed[0][0] value until the function is done? It may not have a real impact on my small script, but I really am interested in the answer at least. Regards, Tri.