czardas Posted March 17, 2016 Author Posted March 17, 2016 (edited) @stealthmsgr Thanks for the . It is my wish that the topic be helpful in understanding multidimensional arrays, and I'm also learning new things as I develop this UDF. There is a good tutorial in the Wikipedia about arrays, and there are many helpful members in The General Help and Support Forum who can answer any questions you might have (equally well as I can). If you don't get an answer for a problem there, then I might not know the answer either, but I will always be happy to help if I can. Edited March 17, 2016 by czardas coffeeturtle 1 operator64 ArrayWorkshop
stealthmsgr Posted March 17, 2016 Posted March 17, 2016 (edited) Thanks so much. As I looked over your UDF I wondered if I could utilize it in my quest. However it may be over-kill. At any rate here's my need. I have a series of updates to be sent out to workstations. I will change the build # of the application at the same time. To keep it simple I just use a text file associated with it. I'm intending to use an INI file to keep track of the version info. What I would like to do is to read in the INI compare it in an array and verify that patch #x is the next patch in sequence and error if not. or at least something to that effect. Well that is my concept. Being as I am new to arrays, I'm in a bit of a sticky patch here. Guidance would be appreciated. Cheers. In retrospect, I may have inadvertently put this into the wrong section. My apologies. Edited March 17, 2016 by stealthmsgr acknowledge possible wrong section.
czardas Posted March 18, 2016 Author Posted March 18, 2016 (edited) 13 hours ago, stealthmsgr said: In retrospect, I may have inadvertently put this into the wrong section. I'm not fussy about things like that, but it is a general question. There are several ways you could proceed. I tend to use CSV when I need to store the contents of an array in a file. Using INI format may be suitable for your purposes. Both these methods have their drawbacks. Another method could be to use jguinch's UDF: storing the declaration string in a text file - especially useful for numeric data and very easy to use. There are also SQLite database functions you could try, but that's probably overkill. You don't need to use more than 2 dimensions for this, so the standard Array UDF is quite suitable. This library still needs rigorous testing for very large arrays: it may be better in some circumstances, and worse in others. For example _ArraySortXD() is pretty fast for a 2D arrays with many columns. Edited March 18, 2016 by czardas operator64 ArrayWorkshop
stealthmsgr Posted March 18, 2016 Posted March 18, 2016 (edited) Many thanks czardas for the link, info and advice. I would like to have a speedy response in the version checking. As I put this together I'll post some code, although it may be clunky for review. Cheers. #include <File.au3> #include <Array.au3> #include <MsgBoxConstants.au3> #include <ArrayMultiDim2.au3> Func _Comparever() Global $avArray1[2] Global $avArray2[2] Global $Ver1 = IniRead("C:\Version\Appver_1.ini", "Version", "Ver", "") Global $Ver2 = IniRead("C:\Version\Appver_2.ini", "Version", "Ver", "") $avArray1[0] = $Ver1 $avArray2[0] = $Ver2 $iRet = _ArrayCompare($avArray1, $avArray2) If $iRet Then MsgBox(0, "", "Array has exactly the same size and values") Else MsgBox(0, "", "Array do not have the same size and values.") EndIf EndFunc I'm missing something here. Edited March 18, 2016 by stealthmsgr add sample code for review
czardas Posted March 18, 2016 Author Posted March 18, 2016 I don't have time to test it ATM and I also have a bit of a headache. Don't use 'Global' inside a function - use 'Local' instead. If you have a question about jguinch's functions, then he's the best person to ask. operator64 ArrayWorkshop
stealthmsgr Posted March 18, 2016 Posted March 18, 2016 No problem. I'll use local and BTW I have found the error. czardas 1
czardas Posted April 7, 2016 Author Posted April 7, 2016 (edited) New Version 0.2.1-beta (see 1st post) ; ============================================================================================================================== ; Changes between versions 0.2.0-beta and 0.2.1-beta ; _ArrayAttach - Added a check for the output array size maximum limit. ; _ShuffleArray - Rewrote the code to be used with the option $iDimension = 0. ; _DeleteRegion - New Function added. ; _ArrayUniqueXD - Replaces the depreciated function _UniqueRegion. ; _ReverseArray - New Function added. ; ============================================================================================================================== This release includes several improvements on the existing code (some small changes are not mentioned). The biggest change is the renaming of _UniqueRegion() to _ArrayUniqueXD(). Anyone who was using it will have to change the function name in scripts that are affected. Also, tests have been carried out on _ArraySortXD() for up to 16 million elements. Expect more functions, and be aware that some error codes may also change, in the not too distant future. Now let's peel that spud! #include 'ArrayWorkshop.au3' ; Delete the outer regions of a cube Local $aCube = [[['0','1','2','3'],['4','5','6','7'],['8','9','A','B'],['C','D','E','F']], _ [['G','H','I','J'],['K','X','X','N'],['O','X','X','R'],['S','T','U','V']], _ [['W','X','Y','Z'],['a','X','X','d'],['e','X','X','h'],['i','j','k','l']], _ [['m','n','o','p'],['q','r','s','t'],['u','v','w','x'],['y','z','=','?']]] Local $aCore = ArrayCore3D($aCube) ; see what remains ConsoleWrite("The Cube Core" & @LF & @LF) For $i = 0 To UBound($aCore) -1 For $j = 0 To UBound($aCore, 2) -1 For $k = 0 To UBound($aCore, 3) -1 ConsoleWrite($aCore[$i][$j][$k]) ; should all be X Next ConsoleWrite(@LF) Next ConsoleWrite(@LF) Next Func ArrayCore3D($aArray) ; remove the outer elements to reveal the core If Not (IsArray($aArray) And UBound($aArray, 0) = 3 And UBound($aArray) > 2 And UBound($aArray, 2) > 2 And UBound($aArray, 3) > 2) Then Return SetError(1) _DeleteRegion($aArray, 1) ; delete top ... [example] bounds [4][4][4] ==> [3][4][4] _DeleteRegion($aArray, 1, UBound($aArray) -1) ; delete bottom ... [3][4][4] ==> [2][4][4] _DeleteRegion($aArray, 2) ; delete left side ... [2][4][4] ==> [2][3][4] _DeleteRegion($aArray, 2, UBound($aArray, 2) -1) ; delete right side ... [2][3][4] ==> [2][2][4] _DeleteRegion($aArray, 3) ; delete front ... [2][2][4] ==> [2][2][3] _DeleteRegion($aArray, 3, UBound($aArray, 3) -1) ; delete back ... [2][2][3] ==> [2][2][2] Return $aArray EndFunc ;==> ArrayCore3D @iamtheky Above are the bare bones of your Rubix core extraction. With a little modification (extracting each region immediately before deletion) the regions could be reattached to produce the original cube. In this case, a bespoke function should probably manipulate the core directly instead, but the idea is useful for demonstration purposes. Edited April 7, 2016 by czardas iamtheky 1 operator64 ArrayWorkshop
czardas Posted April 9, 2016 Author Posted April 9, 2016 (edited) After some consideration, I'm wondering if more functions are actually needed in this library. Inserting or swapping regions can be done with the existing functions already. Does an array ever need to be transposed? I'm still contemplating that last question. Rather than add more functions, perhaps I ought to think more about improvements to functionality with the existing library. The example below demonstrates one method for swapping two regions within a 2D array. The same method could be used to reorder tables in a 3D stack etc... #include 'ArrayWorkshop.au3' #include <Array.au3> ; swapping two regions Local $aArray = [[0,1,2,3,4,5,6,7,8,9], _ ['a','b','c','d','e','f','g','h','i','j']] _ArrayDisplay($aArray, "before swapping columns") ; swap columns 1, 2, 3 with 6, 7 Local $iDimension = 2, $aNew = _ExtractRegion($aArray, $iDimension) ; start with col 0 _ArrayAttach($aNew, _ExtractRegion($aArray, $iDimension, 6, 2), $iDimension) ; add cols 6, 7 _ArrayAttach($aNew, _ExtractRegion($aArray, $iDimension, 4, 2), $iDimension) ; add cols 4, 5 _ArrayAttach($aNew, _ExtractRegion($aArray, $iDimension, 1, 3), $iDimension) ; add cols 1, 2, 3 _ArrayAttach($aNew, _ExtractRegion($aArray, $iDimension, 8, 2), $iDimension) ; add cols 8, 9 $aArray = $aNew _ArrayDisplay($aArray, "after swapping columns 1, 2, 3 with 6, 7") Have I thought of everything? I considered inserting dimensions, because _Predim() only prefixes or appends them, but it's not something I'm ever likely to use. Edited April 9, 2016 by czardas iamtheky 1 operator64 ArrayWorkshop
iamtheky Posted April 9, 2016 Posted April 9, 2016 I at one point in time thought i was good with arrays, i was wrong. You are to arrays what @UEZ is to gdi+ czardas 1 ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__)
czardas Posted April 9, 2016 Author Posted April 9, 2016 (edited) 9 hours ago, iamtheky said: You are to arrays what @UEZ is to gdi+ The best compliment a person could possibly receive. It's something of an exaggeration but it's certainly an honor to have read those words. Thanks! Edited April 9, 2016 by czardas operator64 ArrayWorkshop
czardas Posted April 10, 2016 Author Posted April 10, 2016 (edited) On 4/9/2016 at 0:52 PM, czardas said: Does an array ever need to be transposed? @czardas The answer is no, although I was just being lazy. It's still a very useful thing to have. I actually thought it would be more complicated, but it turned out to be one of the easiest functions to write. I kind of got excited so I'm posting it here for now (I'll add it to the next update in a few days time). With two-dimensional arrays, _ArrayTransform() behaves exactly the same as _ArrayTranspose(); because only one transformation is actually possible. With more dimensions, you can reshape the array in a variety of ways. Basically the bounds of each dimension are swapped and the array filled accordingly [see comments in the function header]. A couple of tests appear below the function. Thanks again to @jchd for suggesting some invaluable ideas which really got me thinking. expandcollapse popup#include <Array.au3> #include 'ArrayWorkshop.au3' ; #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 The 1st parameter does not contain any elements. ; |@error = 3 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) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array. Local $aBound = __GetBounds($aArray) If @error Or $aBound[0] = 1 Then Return SetError(2) If $sShape = Default Then $sShape = StringRight('987654321', $aBound[0]) If StringLen($sShape) <> $aBound[0] Or Not StringIsDigit($sShape) Then Return SetError(3) Local $aTrac = StringSplit($sShape, ''), $sTransfer = '$aSource' For $i = 1 To $aBound[0] If $aTrac[$i] > $aBound[0] Or StringInStr($sShape, $aTrac[$i], 0, 2) Then Return SetError(3) ; 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 __SwapSequence1D($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 #Region - tests Local $aArray[4][3] = [[0,1,2],[3,4,5],[6,7,8],[9,'a','']] _ArrayDisplay($aArray, 'Before transformation.') ; Test 2D _ArrayTransform($aArray) _ArrayDisplay($aArray, 'It works!') ; test 3D _Predim($aArray, 3, True) ; prefix another dimension to test 3D _ArrayTransform($aArray, 132) ; [3D] leave the first dimension in place _Predim($aArray, 2, True) ; remove the first dimension we added earlier _ArrayDisplay($aArray, '3D also works.') ; now we are back to the original array #EndRegion Edited April 10, 2016 by czardas operator64 ArrayWorkshop
jchd Posted April 10, 2016 Posted April 10, 2016 I rarely have any idea: all I do is peddle some good ideas of others. czardas 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
czardas Posted April 15, 2016 Author Posted April 15, 2016 (edited) Here's another (practical rather than exciting) example which uses this UDF. I've made several similar functions to this before but never been 100% satisfied. This date sort function will not become part of the ArrayWorkshop library: it's just an experiment and an example of a function which makes use of ArrayWorkshop. The same function could quite easily have been written using the standard array UDF. Suppose you download some statistics in a csv and want to sort the data on a date column. The dates may be formatted in a variety of ways. A common solution to this problem is to corrupt the original information in order to comply with the programmer's expectations. IMO the vernacular tradition should be embraced as much as possible so that normal people can type whatever they want. So once again I present you with yet another imperfect solution (intended for 1D or 2D arrays only). You can set this function to sort US date format (or 'other'). If the format parameter is not recognized (either 'UK' or 'US'), then the dates are treated as being formatted in the logical sequence - year - month - day. It's slightly fuzzy: as one would expect from a function like this! expandcollapse popup#include <Array.au3> #include 'ArrayWorkshop.au3' Local $aRecords = [ _ ['Date','Details','Amount'], _ ['Wed | 10-2-16 ???','ebay','1.00'], _ ['Wed = 1 / 1 / 16','advert','17.87'], _ ['Sun | 8-11-15','insurance','13.05'], _ ['Tue | 22-9-15','hosting','70.34'], _ ['junk-12-21-21-21','ignore','N/A'], _ ['Mon - 4, 4. 16','transport','117.00'], _ ['Sat - 19-03-16','registration','11.00'], _ ['Wed - 01-01-16','power','65.21'], _ ['Sat - 07-11-2015','advert','12.90']] _ArrayDisplay($aRecords) SortByDate($aRecords, 'UK', 1) _ArrayDisplay($aRecords) Func SortByDate(ByRef $aArray, $sFormat = 'UK', $iStart = 0, $iEnd = -1, $iCol = 0) ; Strips any non-numeric characters from the start or end of the string. ; Tries to identify a date which includes the delimiters -,./\ or space. ; Delimiters may also be padded by a single space character on the left and/or the right. [max = 3 chars] If Not IsArray($aArray) Or UBound($aArray, 0) > 2 Or UBound($aArray) = 0 Then Return SetError(1) ; $aArray is not valid If $sFormat = Default Then $sFormat = 'UK' ; change the Default format to US if you like [requires two edits] Local $iDay, $iMon, $iYear = 4 Switch $sFormat Case 'UK' ; day, month, year $iDay = 0 $iMon = 2 Case 'US' ; month, day, year $iDay = 2 $iMon = 0 Case Else ; year, month, day $iDay = 4 $iMon = 2 $iYear = 0 EndSwitch $iStart = ($iStart = Default) ? 0 : Int($iStart) Local $iBound = UBound($aArray) $iEnd = ($iEnd = Default Or $iEnd = -1) ? $iBound -1 : Int($iEnd) If $iEnd < 1 Or $iEnd >= $iBound Then Return SetError(3) ; bad $iEnd parameter If $iStart < 0 Or $iStart >= $iEnd Then Return SetError(2) ; bad $iStart parameter Local $iNewIdx, $b2D = UBound($aArray, 0) = 2 ? True : False If $b2D Then $iNewIdx = UBound($aArray, 2) ; new column to sort on If $iNewIdx = 0 Then Return SetError(1) ; $aArray is not valid $iCol = ($iCol = Default) ? 0 : Int($iCol) Else $iNewIdx = 1 ; new column to sort on $iCol = 0 _Predim($aArray, 2) EndIf If $iCol >= $iNewIdx Or $iCol < 0 Then Return SetError(4) ; bad $iCol parameter ReDim $aArray[$iBound][$iNewIdx +1] Local $sTemp, $aRegExp, $sCentury = StringLeft(@YEAR, 2) For $i = $iStart To $iEnd $sTemp = StringRegExpReplace($aArray[$i][$iCol], '(?i)(\A\D*)(?U)(.*)(\D*\z)', '$2') ; try to identify a date [\D* strips leading/trailing non-numeric garbage] $aRegExp = StringRegExp($sTemp, '[\d]+|( ?[ ,/\Q.-\\E]\ ?)', 3) ; attempt to split the cropped result If IsArray($aRegExp) And UBound($aRegExp) = 5 And StringLen($aRegExp[$iDay]) < 3 And StringLen($aRegExp[$iMon]) < 3 And StringLen($aRegExp[$iYear]) < 5 Then If StringLen($aRegExp[$iYear]) = 2 Then $aRegExp[$iYear] = $sCentury & $aRegExp[$iYear] ; two digit years default to the current century $aArray[$i][$iNewIdx] = StringFormat("%04i%02i%02i", $aRegExp[$iYear], $aRegExp[$iMon], $aRegExp[$iDay]) ; add each formatted date to the temporary column Else $aArray[$i][$iNewIdx] = 'z' & StringFormat('%08i', $i) ; non-matching values get dumped at the end EndIf Next _ArraySortXD($aArray, 1, 0, $iEnd, $iStart, $iNewIdx) ; dim = 1, algo = 0, end = -1, row = 0, col = final column If $b2D Then ReDim $aArray [$iBound][$iNewIdx] ; delete the temporary column Else _PreDim($aArray, 1) ; delete the temporary dimension EndIf EndFunc ;==> SortByDate One would expect the dates in the date column to be of a consistent format, but the function doesn't care about this, nor whether a date is genuine. It is assumed that these concerns have already been addressed at the time of data entry. This is about as wide as I am prepared to cast the net because this function is designed to embrace the most common numeric based (date) formats used by people throughout the world (not necessarily formats generated, or recognized, by computer programs). Work on ArrayWorkshop.au3 will resume shortly. Edited April 15, 2016 by czardas operator64 ArrayWorkshop
czardas Posted April 26, 2016 Author Posted April 26, 2016 (edited) Update version 0.2.2-beta in the first post. ; Changes between versions 0.2.1-beta and 0.2.2-beta ; _ArrayTransform - New Function added. ; _InsertRegion - New Function added. ; _SearchArray - New parameter added - optional search algorithm for typical string matching criteria. ; AU3Stripper - Added directive for AU3Stripper to ignore ArrayWorkshop altogether - a necessary precaution with AU3Stripper. Earlier versions were not compatible with AU3Stripper for various reasons. Nearly all functions rely on executed string instructions which are not visible. Until a full analysis of all affected areas has been done, the whole script has been protected. You can still use AU3Stripper. Any extra bloat has to be put into perspective: considering the thousands of lines of code that would have been required to produce this library without using remote loops and hidden function calls. It's no big deal. Edited April 26, 2016 by czardas operator64 ArrayWorkshop
czardas Posted May 2, 2016 Author Posted May 2, 2016 (edited) Due to a leak in an error check for _ArrayTransform() in version 0.2,2, I have decided to release this update slightly ahead of schedule. ; Changes between versions 0.2.2-beta and 0.2.3-beta ; _ArrayTransform - Fixed leak in error check for bad shape parameter. [corrections also made to documentation] ; _ArrayUniqueXD - Implemented scripting dictionary: to generate unique keys. ; _ArraySortXD - Algorithm 256 now accepts numeric strings with leading/trailing whitespaces, includes WS after the sign symbol. After further analysis, and for reasons mentioned earlier, I have decided to create a tool to generate stripped down (and compressed) versions of this UDF to meet individual requirements. Several other example scripts are also affected by similar problems. Always test compiled scripts fully before release. Edited May 2, 2016 by czardas operator64 ArrayWorkshop
czardas Posted May 20, 2016 Author Posted May 20, 2016 (edited) First Stable Release [see 1st post] ; ============================================================================================================================== ; Changes between versions 0.2.3-beta and 1.0.0 [1st stable release] ; _ShuffleArray - Removed the dependency on _ArrayFlatten. [optimization for fruit-machine style] ; _ArrayUniqueXD - Increased the maximum number of dimensions to 9 [heaven knows idea why] ; __TagSortSwap - Renamed internal function. [Original name ==> __SwapSequence1D] ; __TagSortSwapXD - Renamed internal function. [Original name ==> __SwapSequence2D] ; ___Search1D - Modifications to reduce bloat. [internal function] ; _ArrayFlatten - Depreciated function. [Removed] ; __CountElements - Depreciated internal function. [Removed] ; ___Read1D - Depreciated internal function. [Removed] ; ============================================================================================================================== When I started writing this UDF I really just wanted to have support for up to 3, and perhaps 4, dimensions for standard array functions. With several future projects in mind, I increased the number of dimensions to 9, gradually modifying the approach as I tried different methods. One of the targets I set myself was a limit of 2000 lines of code - including documentation. Admittedly I wandered down some well trodden paths, but that's all part and parcel of the learning curve. _ArrayFlatten() was originally introduced as a helper function for _ShuffleArray(). This currently depreciated function was neither sophisticated nor discerning about how the array became one dimensional, providing the amount of data was preserved: exact data location didn't matter. DEPRECIATED FUNCTION expandcollapse popup#include 'ArrayWorkshop.au3' ; needed for __GetBounds() ; #FUNCTION# =================================================================================================================== ; Name...........: _ArrayFlatten ; Description ...: Turns a multidimensional array into a one dimensional array while maintaining all the data. ; Syntax.........: _ArrayFlatten($aArray) ; Parameters.....; $aArray - The original array. ; Return values .: Returns the modified array ByRef. ; Failure sets @error as follows: ; |@error = 1 The parameter is not a valid array. ; |@error = 2 Dimension limit exceeded. ; |@error = 3 Arrays must contain at least one element. ; Author.........: czardas ; Comments ......; This function works for up to 9 dimensions. ; ============================================================================================================================== Func _ArrayFlatten(ByRef $aArray) ; <== DO NOT RENAME If Not IsArray($aArray) Then Return SetError(1) Local $aBound = __GetBounds($aArray, 9) If @error Then Return SetError(3) ; $aArray must contain at least one element If $aBound[0] > 9 Then Return SetError(2) If $aBound[0] = 1 Then Return ; array is already one dimensional For $i = 1 To 9 $aBound[$i] = ($i > $aBound[0]) ? 0 : $aBound[$i] - 1 Next Local $aTarget[__CountElements($aArray)], $iCount = 0, _ $sExpression = '$aArray' & StringLeft('[$1][$2][$3][$4][$5][$6][$7][$8][$9]', $aBound[0] * 4) 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] $aTarget[$iCount] = Execute($sExpression) $iCount += 1 Next Next Next Next Next Next Next Next Next $aArray = $aTarget EndFunc ;==>_ArrayFlatten ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Description ...: Return the total number of elements contained within a multidimensional array. ; ============================================================================================================================== Func __CountElements($aArray) Local $iCount = 1 For $i = 1 To UBound($aArray, 0) $iCount *= UBound($aArray, $i) Next Return $iCount EndFunc ;==>__CountElements As far as building a stripper for ArrayWorkshop.au3 is concerned, it will have to wait a little while longer because I have a big work load - as usual. In the mean while, anyone brave enough to have a go themselves can try these suggestions: 1. DO NOT remove the directives #Au3Stripper_Off or #Au3Stripper_On. 2. Remove unused functions and unused dependencies [see the table below]. 3. Remove 'remote-loop' code and parameters from unused (higher) dimensions, but leave all nine ___FloodXD function names alone. 4. Don't try and rename anything. ; Dependency Tree for each function (including interdependencies) ; _ArrayAttach __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, ___NewArray, __ResetBounds, _PreDim ; _ArraySortXD __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, ___NewArray, __Separate1D,__QuickSort1D, __CreateTrac, __Separate256, __QuickSortXD, ; __SeparateXD, ___Reverse1D, __TagSortSwap, __ExtractVector, __TagSortSwapXD, __AcquireExponent, ___FormatNum, ___NumCompare ; _ArrayTransform __GetBounds, __FloodFunc, ___FloodXD, ___NewArray, __TagSortSwap ; _ArrayUniqueXD __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, __ResetBounds ; _DeleteDimension __GetBounds, __FloodFunc, ___FloodXD, ___NewArray ; _DeleteRegion __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, __ResetBounds ; _ExtractRegion __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, ___NewArray ; _InsertRegion __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, ___NewArray, __ResetBounds, _ArrayAttach, _ExtractRegion, _PreDim ; _PreDim __GetBounds, __FloodFunc, ___FloodXD, ___NewArray ; _ReverseArray __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices,___NewArray, ___Reverse1D ; _SearchArray __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, __ResetBounds, ___Search1D, __FindExact, __FindString, __FindWord, ; __FindExactCase, __FindStringCase, __FindWordCase, $g__ARRWSHOP_RESUME, $g__ARRWSHOP_SUB ; _ShuffleArray __GetBounds, __FloodFunc, ___FloodXD, __HiddenIndices, ___NewArray, __Shuffle1D, __ShuffleXD As an example here is the code needed if you only want to include _ArrayTransform() for three dimensions. expandcollapse popup#include-once #Au3Stripper_Off 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 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 Func __FloodFunc() Local $aFloodFunc = ['', ___Flood1D, ___Flood2D, ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D] Return $aFloodFunc EndFunc ;==>__FloodFunc 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 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 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 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 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 ; CODE REMOVED FOR HIGHER DIMENSIONS Func ___Flood4D() EndFunc ;==>___Flood4D Func ___Flood5D() EndFunc ;==>___Flood5D Func ___Flood6D() EndFunc ;==>___Flood6D Func ___Flood7D() EndFunc ;==>___Flood7D Func ___Flood8D() EndFunc ;==>___Flood8D Func ___Flood9D() EndFunc ;==>___Flood9D #Au3Stripper_On More modifications can be made to the example above, but I advise caution against doing so. Removing unused parts of the remote-loop code (as shown above) should be safe, providing that you fully test everything is working before compiling the script. Other code modifications cannot be guaranteed to work in every situation. I think the amount of bloat is reasonable, even without any attempt to strip it down. Bear in mind that any changes you make are at your own risk. Any questions about this, feel free to ask. Edited May 21, 2016 by czardas operator64 ArrayWorkshop
czardas Posted March 19, 2017 Author Posted March 19, 2017 (edited) I just spotted a bug affecting _ArrayUniqueXD(), introduced in the last updated version. I doubt anyone using the function will have noticed a problem, but it's only a matter of time before such circumstances occur. I have updated the first post to version 1.0.1 (minimal changes). ; ============================================================================================================================== ; Changes between versions 1.0.0 and 1.0.1 ; _ArrayUniqueXD - Bug introduced in version 1.00 [line 447] ExitLoop 5 should have been changed to ExitLoop 9. ; ============================================================================================================================== Edited March 19, 2017 by czardas coffeeturtle 1 operator64 ArrayWorkshop
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