DasBo Posted June 20, 2008 Share Posted June 20, 2008 This may be sort of a happy problem, but I wonder if it is possible to create a real empty array, that can be filled in a loop without any special treatment of the first array element. A little example to clarify, what I mean/want: #include <Array.au3> ; First example works, because the first array element is treated separately Dim $foo[1] For $i=1 To 10 If $i=1 Then $foo[0]=$i Else _ArrayAdd($foo,$i) EndIf Next ; Second example would be much easier to write and read (and btw it would probably be a bit faster), ; but doesn't work, because Dim drops an 'Array variable subscript badly formatted.' error Dim $foo[0] For $i=1 to 10 _ArrayAdd($foo,$i) Next ; Third example doesn't work either. This time _ArrayAdd() fails with @error=1, because ; it is called with a non-array variable. $foo="" For $i=1 to 10 _ArrayAdd($foo,$i) Next I hope you see, what I mean. Is there any way to do something like this without If/Else or extra counter variables? Just for beauty (and speed) ? Link to comment Share on other sites More sharing options...
ChrisL Posted June 20, 2008 Share Posted June 20, 2008 Is this what you mean? Dim $foo[11] [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
DasBo Posted June 20, 2008 Author Share Posted June 20, 2008 (edited) Is this what you mean? Dim $foo[11] Ok, I missed to note, that I want to create arrays with unknown size. The For/Next example is a bit misleading in this case. I used it to get a minimum example for filling an array with some meaningful values. Actually I want to use this with While/Wend loops, f.e. for reading files/lists of unknown size or similar tasks. Edited June 20, 2008 by Jeas Link to comment Share on other sites More sharing options...
ProgAndy Posted June 20, 2008 Share Posted June 20, 2008 (edited) Some time ago, there was the same question: http://www.autoitscript.com/forum/index.ph...st&p=392109 Edited June 20, 2008 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
andybiochem Posted June 20, 2008 Share Posted June 20, 2008 (edited) I don't think you can create a totally empy array in AutoIt. Your simple example: Dim $foo[0] For $i=1 to 10 _ArrayAdd($foo,$i) Next ...doesn't work because you are trying to create an array with no elements: Dim $foo[0] use this instead: Dim $foo[1] For $i=1 to 10 _ArrayAdd($foo,$i) Next ...this way you don't have to commit to an array size before hand, and the _ArrayAdd UDF will ReDim the array each time automatically. If you are doing this on a mass-scale array with several thousand elements you will see a performance drop using _ArrayAdd, when compared to other methods. I'm not sure why there is a problem with arrays being zero-based along with everything else in autoit, I find them really easy to use. Edited June 20, 2008 by andybiochem Bluesmaster 1 - Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar! Link to comment Share on other sites More sharing options...
FreeFry Posted June 20, 2008 Share Posted June 20, 2008 He could also use the ReDim function: Dim $Array[1] For $i = 1 To 10 ReDim $Array[$i] $Array[0] = $i ; If you want to store the size of the array(not really necessary because of the UBound command). Next Or am I missing something? Link to comment Share on other sites More sharing options...
Siao Posted June 20, 2008 Share Posted June 20, 2008 (edited) ReDim is very expensive, and doing it for each change to the array in a loop is bad practice (same as _ArrayAdd). Edited June 20, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
ChrisL Posted June 20, 2008 Share Posted June 20, 2008 Ok, I missed to note, that I want to create arrays with unknown size. The For/Next example is a bit misleading in this case. I used it to get a minimum example for filling an array with some meaningful values. Actually I want to use this with While/Wend loops, f.e. for reading files/lists of unknown size or similar tasks. Do you mean like this? #include <array.au3> Dim $foo[1] For $i = 1 to Random(2,50,1);random number somewhere between 2 and 50 ReDim $foo[Ubound($foo) + 1];resize the array by 1 from the previous size $foo[0] +=1;set the 0 element to update the count if you want to $foo[Ubound($foo) - 1] = "My data I want to put in " & $i;set the data to the last created element Next _ArrayDisplay($foo) [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
Kip Posted June 20, 2008 Share Posted June 20, 2008 $ARRAY[1] = [0] MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API. Link to comment Share on other sites More sharing options...
Kovitt Posted June 20, 2008 Share Posted June 20, 2008 (edited) Ignore This.. Edited June 20, 2008 by Kovitt Link to comment Share on other sites More sharing options...
ChrisL Posted June 20, 2008 Share Posted June 20, 2008 I think you want Dim $foo ;with no specified sizeThis would create an empty dynamic array..No it wouldn't that would initialise a variable not an array [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
Richard Robertson Posted June 20, 2008 Share Posted June 20, 2008 Good code technique says to declare an array and not change the size of it. You should have a way to figure out in advance how many items you need. Link to comment Share on other sites More sharing options...
DasBo Posted June 20, 2008 Author Share Posted June 20, 2008 Do you mean like this? #include <array.au3> Dim $foo[1] For $i = 1 to Random(2,50,1);random number somewhere between 2 and 50 ReDim $foo[Ubound($foo) + 1];resize the array by 1 from the previous size $foo[0] +=1;set the 0 element to update the count if you want to $foo[Ubound($foo) - 1] = "My data I want to put in " & $i;set the data to the last created element Next _ArrayDisplay($foo) Most solutions (also in the thread mentioned by ProgAndy) init the array with one element, using $foo[0] as an array counter later on. Of course this is a common solution to the problem. But, strictly speaking, it wastes an array element for saving an information, that can be retrieved much more reliable by using UBound(). And sometimes, the first (wasted) element even interferes with program logic, for example when handling lists, that "naturally" count from zero upward (imagine for example arrays that do something with floors in a building or age of peoples). Link to comment Share on other sites More sharing options...
FreeFry Posted June 21, 2008 Share Posted June 21, 2008 ReDim is very expensive, and doing it for each change to the array in a loop is bad practice (same as _ArrayAdd).Yes, but that's what the thread starter wanted is it not?To create an "empty" array, and fill it up afterwards(even if it's expensive as you say) Link to comment Share on other sites More sharing options...
ChrisL Posted June 21, 2008 Share Posted June 21, 2008 Most solutions (also in the thread mentioned by ProgAndy) init the array with one element, using $foo[0] as an array counter later on. Of course this is a common solution to the problem. But, strictly speaking, it wastes an array element for saving an information, that can be retrieved much more reliable by using UBound(). And sometimes, the first (wasted) element even interferes with program logic, for example when handling lists, that "naturally" count from zero upward (imagine for example arrays that do something with floors in a building or age of peoples). Well you seem to be an expert on the matter but I'm not sure I understand what you actually want. Here is my next attempt, is this it? No counter in element 0 just the data started straight way #include <array.au3> Dim $foo[1] For $i = 0 to Random(2,50,1);random number somewhere between 2 and 50 $foo[Ubound($foo) - 1] = "My data I want to put in " & $i;set the data to the last element ReDim $foo[Ubound($foo) + 1];resize the array by 1 for the next bit of data Next ReDim $foo[Ubound($foo) - 1];After the loop finishes resize the array by -1 from the previous size to clear the last blank element we created in anticipation of more data (wouldn't want any waste now would we!) _ArrayDisplay($foo) [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
DasBo Posted June 22, 2008 Author Share Posted June 22, 2008 Well you seem to be an expert on the matter but I'm not sure I understand what you actually want. Here is my next attempt, is this it? No counter in element 0 just the data started straight way #include <array.au3> Dim $foo[1] For $i = 0 to Random(2,50,1);random number somewhere between 2 and 50 $foo[Ubound($foo) - 1] = "My data I want to put in " & $i;set the data to the last element ReDim $foo[Ubound($foo) + 1];resize the array by 1 for the next bit of data Next ReDim $foo[Ubound($foo) - 1];After the loop finishes resize the array by -1 from the previous size to clear the last blank element we created in anticipation of more data (wouldn't want any waste now would we!) _ArrayDisplay($foo) Yes, this is roughly, what I'm doing in practice - deleting either the first or the last element after a loop. But the additional step remains even with this solution. If it would be possible to create a real empty array in AutoIt (in other programming languages this would be sort of a pointer), you don't need to pay any extra attention to the first element or delete the first or last element after building the array to get an array that holds nothing but the data you want to save in it. If there is no similar solution for this problem in AutoIt, I have no problem with that. I just wanted to ask the experts in this forum, if I'm just blind or if there is really no other/better solution to this problem. Well - the latter seems to be the case. Link to comment Share on other sites More sharing options...
enaiman Posted June 23, 2008 Share Posted June 23, 2008 Hmm, you keep saying that you're wasting an element ([0]), IMHO you're wrong about that. If you create an array you can use all its elements (element [0] as well) to store whatever you like. You do "waste" the element [0] when a function is returning an array and it uses [0] to store the number of elements (you can copy that array to a new one and use [0] for your purpose if the element count is bothering you). SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script wannabe "Unbeatable" Tic-Tac-Toe Paper-Scissor-Rock ... try to beat it anyway :) Link to comment Share on other sites More sharing options...
Leandroz Posted June 19, 2009 Share Posted June 19, 2009 I miss this Dim $array[0] as well. It's possible in literally every computer language I've ever known except AutoIt. An empty array is just as meaningful as an array with elements. Using the UBound($array)-1 means you have to remember which arrays have the added [0] element and which don't. More importantly; some AutoIt functions use element [0] for data, some use it for meta-data. This means you cannot simply use the UBound($array)-1 trick and assume it means what you expect. Anyway, one fix I use is to simply _ArrayDelete($array, 0) after you're done filling the array. Link to comment Share on other sites More sharing options...
Yoriz Posted June 19, 2009 Share Posted June 19, 2009 How about using a delimeter string inside the loop and then a string split to create the array afterwards, works out much faster then all the redims ; Method one $begin1 = TimerInit() Dim $foo[1] For $i = 1 to 1000 ReDim $foo[Ubound($foo) + 1];resize the array by 1 from the previous size $foo[0] +=1;set the 0 element to update the count if you want to $foo[Ubound($foo) - 1] = "My data I want to put in " & $i;set the data to the last created element Next $dif1 = TimerDiff($begin1) $begin2 = TimerInit() ;Method two Local $sStore,$foo[1] For $i = 1 to 1000 $sStore = $sStore & "My data I want to put in " & $i & "|" Next $sStore = StringTrimRight($sStore,1) $foo = StringSplit($sStore,"|") $dif2 = TimerDiff($begin2) MsgBox(0,"", "Method one time = " & $dif1 & @CR & "Method two time = " & $dif2) ;Method one time = 656.480362727665 ;Method two time = 30.0105180965737 GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF. Link to comment Share on other sites More sharing options...
CodeWriter Posted December 1, 2017 Share Posted December 1, 2017 After lots of experimenting, I found a way to declare at least a 1D an empty array (doesn't use Dim): #include <Array.au3> Local $foo[0] For $i=1 To 10 _ArrayAdd($foo, $i) Next _ArrayDisplay($foo) 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