leuce Posted March 13, 2014 Share Posted March 13, 2014 (edited) Hello everyoneSuppose I have a for-next loop like this: For $i = 1 to 9 ; Do something that involves $i NextBut I don't want $i to go from 1 to 9 in numerical order, but instead I want $i to use the range 1 to 9 randomly (or semi-randomly), and use every number only once, how would I do that?In other words, instead of letting $i be this:1 then 2 then 3 then 4 then 5 etcI want it $i to be e.g. this:2 then 5 then 7 then 9 then 4 etcusing each of the items 1 to 9 only once.It doesn't have to be a for-next loop if there is a better way of doing it. The application of this is to read a file with e.g. 9 lines in it, in which I do something with each of the lines (one line at a time) in random order.If you could just point me in the right direction, please...ThanksSamuelAdded: Oh, in this example I used "1 to 9" but the actual file I'm going to process will have about 10 000 lines. Edited March 13, 2014 by leuce Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 13, 2014 Moderators Share Posted March 13, 2014 leuce,I would create an array holding 1-9 and then shuffle it - looping from 1 to 9 now will produce those values in a random order. Here is an example using the _ArrayShuffle function that will be in the next AutoIt release: expandcollapse popup#include <Array.au3> Global $aArray[10] For $i = 1 To 9 $aArray[$i] = $i Next _ArrayDisplay($aArray, "Default", Default, 8) _ArrayShuffle($aArray, 1, 0) _ArrayDisplay($aArray, "Shuffled", Default, 8) Func _ArrayShuffle(ByRef $avArray, $iStart_Row = 0, $iEnd_Row = 0, $iCol = 0) ; Fisher–Yates algorithm If $iStart_Row = Default Then $iStart_Row = 0 If $iEnd_Row = Default Then $iEnd_Row = 0 If $iCol = Default Then $iCol = 0 If Not IsArray($avArray) Then Return SetError(1, 0, -1) Local $iDim_1 = UBound($avArray, $UBOUND_ROWS) If $iEnd_Row = 0 Then $iEnd_Row = $iDim_1 - 1 If $iStart_Row < 0 Or $iStart_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1) If $iEnd_Row < 1 Or $iEnd_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1) If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1) Local $vTmp, $iRand Switch UBound($avArray, $UBOUND_DIMENSIONS) Case 1 For $i = $iEnd_Row To $iStart_Row + 1 Step -1 $iRand = Random($iStart_Row, $i, 1) $vTmp = $avArray[$i] $avArray[$i] = $avArray[$iRand] $avArray[$iRand] = $vTmp Next Return 1 Case 2 Local $iDim_2 = UBound($avArray, $UBOUND_COLUMNS) If $iCol < 0 Or $iCol > $iDim_2 - 1 Then Return SetError(5, 0, -1) Local $iCol_Start, $iCol_End If $iCol Then $iCol_Start = $iCol $iCol_End = $iCol Else $iCol_Start = 0 $iCol_End = $iDim_2 - 1 EndIf For $i = $iEnd_Row To $iStart_Row + 1 Step -1 $iRand = Random($iStart_Row, $i, 1) For $j = $iCol_Start To $iCol_End $vTmp = $avArray[$i][$j] $avArray[$i][$j] = $avArray[$iRand][$j] $avArray[$iRand][$j] = $vTmp Next Next Return 1 Case Else Return SetError(2, 0, -1) EndSwitch EndFunc ;==>_ArrayShuffleThat should do the trick for you. M23 leuce 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Solution water Posted March 13, 2014 Solution Share Posted March 13, 2014 (edited) Let's say you read the file into an array and mark all processed entries ("****" in this example): Global $aArray[1], $iItem, $iProcessed = 0, $sFilename = "Your input file" FileReadToArray($sFilename, $aArray) While 1 $iItem = Random(1, $aArray[0], 1) If $aArray[$iItem] <> "****" Then ; insert code to process this record here !! $aArray[$iItem] = "****" ; Mark as processed $iProcessed = $iProcessed + 1 If $iProcessed = $aArray[0] Then ExitLoop EndIf WEnd Edited March 13, 2014 by water My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
leuce Posted March 13, 2014 Author Share Posted March 13, 2014 Let's say you read the file into an array and mark all processed entries...Thanks, that's quite a simple solution. Link to comment Share on other sites More sharing options...
czardas Posted March 13, 2014 Share Posted March 13, 2014 (edited) The problem with Water's answer is that you may keep hitting the same element. With a large array you will be in trouble. The solution is to shuffle the array elements first and then run through them one by one. . ; ==================================================================================================================== ; Name...........: _ArrayShuffle ; Description ...: Shuffles the elements within a one dimensional array. ; Syntax.........: _ArrayShuffle(ByRef $avArray) ; Parameters ....: $avArray - [ByRef] The array to shuffle ; Return values .: Success - Returns 1 ; Failure - Returns zero and sets @error to the following values: ; |@error = 1 : $avArray is not a one dimensional array ; Author ........: jchd ; Modified.......: czardas ; Related .......: _MultiDimShuffle ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _ArrayShuffle(ByRef $avArray) If Not IsArray($avArray) Or UBound($avArray, 0) > 1 Then Return SetError (1) Local $vTemp, $r, $iBound = UBound($avArray) -1 For $i = 0 To $iBound $r = Random(0, $iBound, 1) $vTemp = $avArray[$i] $avArray[$i] = $avArray[$r] $avArray[$r] = $vTemp Next Return 1 EndFunc ;==> _ArrayShuffle ; Oh, I just noticed M23 also suggested this approach. Edited March 13, 2014 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
water Posted March 13, 2014 Share Posted March 13, 2014 (edited) I just checked and it only takes 0.2 seconds to process 10000 records. I feared to be worse Edited March 13, 2014 by water My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
czardas Posted March 13, 2014 Share Posted March 13, 2014 (edited) There should be a variable processing time ranging from very quick to very very slow - depending on how reliable Random() is. I imagine the longest possible duration to be years, or if Random() is really good, then it could possibly take millenia - theoretically speaking. Keep rolling a dice and always landing on 6 is unlikely though. Edited March 13, 2014 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
water Posted March 13, 2014 Share Posted March 13, 2014 I have run my code 1000 times in a loop and the max. processing time was 0.438 seconds. Seems Random returns real random numbers My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now