Jump to content
czardas

ArrayWorkshop

Recommended Posts

czardas

EXAMPLES

Fruit Machine

#include <Array.au3>
#include <MsgBoxConstants.au3>
#include 'ArrayWorkshop.au3'

; Example - Fruit Machine
Local $aWheel = ['strawberry', 'cherries', 'melon', 'pomegranate', 'lemon', '7', 'bell', 'BAR', '$']
Local $aFruitMachine = $aWheel ; one dimensional array to start with
For $i = 2 To 3 ; add some more wheels
    _ArrayAttach($aFruitMachine, $aWheel, 2) ; concatenation employed in the second dimension - this is too easy!
Next

For $i = 1 To 5 ; now let's give it a few spins
    _ShuffleArray($aFruitMachine, 2, True) ; shuffle regions of the second dimension with $bFruitMachineStyle set to True
    MsgBox($MB_OK, "Fruit Machine", "[" & $aFruitMachine[0][0] & "] [" & $aFruitMachine[0][1] & "] [" & $aFruitMachine[0][2] & "]")
Next

_ArrayDisplay($aFruitMachine, "Fruit Machine")

Shuffle Columns in a 2D Array

#include <Array.au3>
#include 'ArrayWorkshop.au3'

; Shuffle columns within a 2D array
Local $aTable = [['zero','one','two','three','four','five','six','seven'], _
                 [ 0,    1,    2,    3,      4,     5,     6,    7], _
                 [' ',  'a',  'b',  'c',    'd',   'e',   'f',  'g']]
_ArrayDisplay($aTable, 'before')

_ShuffleArray($aTable, 2) ; standard shuffle in the 2nd dimension [$bFruitMachineStyle = False]
_ArrayDisplay($aTable, 'after')

PreDim Example

#include <Array.au3>
#include 'ArrayWorkshop.au3'

; Example - push all dimensions up one level
Local $aData = ['Header 1','Header 2','Header 3','Header 4','Header 5','Header 6']
_ArrayDisplay($aData, "Original 1D")

_Predim($aData, 2, True) ; push the 1st dimension up one level to the 2nd dimension
_ArrayDisplay($aData, "1D to 2D push")

_Predim($aData, 1, True) ; revert everything back to the way it was
_ArrayDisplay($aData, "2D to 1D push reversed")

Unique Tables - Stacked

#include <MsgBoxConstants.au3>
#include 'ArrayWorkshop.au3'

; Test - Test for uniqueness occurring in the 3rd dimension
MsgBox($MB_OK, 'Msg', 'Keep your eye on the console.', 5)

Local $aGrid[3][3] = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] ; start with a 2-dimensional template

; stack 100 tables using concatenation in the third dimension
Local $aStack = $aGrid, $aTable ; $aTable = temporary array

For $i = 1 To 99
    $aTable = $aGrid ; copy 2D template
    $aTable[Random(0, 2, 1)][Random(0, 2, 1)] = 'X' ; create subtle variety in each table

    ; stack each table
    _ArrayAttach($aStack, $aTable, 3) ; 2D concatenation in the 3rd dimension - [table row][table col][index]

    ; OR stack the tables differently ==> [index][table row][table col]
    ; _PreDim($aTable, 3, True) ; this line should ideally be placed before the loop
    ; _ArrayAttach($aStack, $aTable)
Next

; NB. if you modify the code above, you will also need to modify the code below

ConsoleWrite('$aStack contains ' & UBound($aStack, 3) & ' tables' & _
' with a total of ' & 3 * 3 * UBound($aStack, 3) & ' fields' & @LF)

ConsoleWrite('finished staking tables' & @LF & 'starting timer in 1 second' & @LF & @LF)

Sleep(1000)
Local $iTimer = TimerInit()

; remove duplicate tables
_ArrayUniqueXD($aStack, Default, 3) ; tests for uniqueness in the third dimension
$iTimeDiff = TimerDiff($iTimer)

ConsoleWrite('$aStack now contains ' & UBound($aStack, 3) & ' unique tables' & _
' with a total of ' & 3 * 3 * UBound($aStack, 3) & ' fields ;)' & @LF)
ConsoleWrite('Time Taken - ' & $iTimeDiff & ' ms' & @LF & @LF)

If MsgBox($MB_YESNO, 'Prompt', 'Write the results to console?') = $IDNO Then Exit

; write the unique tables within the 3D Array to the console
For $3 = 0 To UBound($aStack, 3) - 1
    For $1 = 0 To UBound($aStack, 1) - 1
        For $2 = 0 To UBound($aStack, 2) - 1
            ConsoleWrite($aStack[$1][$2][$3])
        Next
        ConsoleWrite(@LF)
    Next
    ConsoleWrite(@LF)
Next

 

Edited by czardas
  • Like 1

Share this post


Link to post
Share on other sites
czardas

New version - BETA release, although it should be stable. More examples to follow.

Testing _ArrayAttach() - 9 Dimensions (quite mad really)

#include <MsgBoxConstants.au3>
#include 'ArrayWorkshop.au3'

; Test - Attach a string to a 1D array in the 9th dimension

Local $aArray = ["hello "]
_ArrayAttach($aArray, "world", 9) ; attach data [added functionality]

Local $sMsg = ""
For $1 = 0 To 0
    For $9 = 0 To 1
        $sMsg &= $aArray[$1][0][0][0][0][0][0][0][$9]
    Next
Next

MsgBox($MB_OK, "9D Read Out", $sMsg)

Testing _DeleteDimension()

#include <Array.au3>
#include 'ArrayWorkshop.au3'

; Test 3 - delete any dimension
Local $aArray[3][1][3] = [[[1,2,3]],[[4,5,6]],[[7,8,9]]]

_DeleteDimension($aArray, 2) ; delete the 2nd dimension from a 3D array
_ArrayDisplay($aArray, '2nd dimension deleted') ; no data loss here [Ubound($aArray, 2) = 1]

 

Edited by czardas

Share this post


Link to post
Share on other sites
UEZ

@czardas can you pack your UDF and the examples into a zip archive please?

 

Thx.


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
UEZ

Looks very impressive!

Thanks for sharing.

  • Like 1

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
spudw2k

Neat stuff.  I wasn't clear on what the _PreDim function was doing at first.  It "looked" like a transposition.  I used a fun Dynamic Array Enumerate function I made used to visualize and understand it.  I noticed it also "seems" to only support up-to 7 dimensions, leaving the original array unchanged.

Local $aData = ['Header 1', 'Header 2', 'Header 3']
_DynEnumArray($aData)

_Predim($aData, 5, True)
_DynEnumArray($aData)

_Predim($aData, 7, True)
_DynEnumArray($aData)

_Predim($aData, 8, True)
_DynEnumArray($aData)

Func _DynEnumArray($arr)
    Local $arrDims[1][2]=[["ElementIdx","ElementCount"]]   ;Create an Array to Track Dimensions and Elements
    For $x = 1 to UBound($arr,0)
        ReDim $arrDims[$x+1][2]
        $arrDims[$x][0]=0
        $arrDims[$x][1]=UBound($arr,$x)
    Next
    Do   ;Loop Through Array Elements
        $var = "$arr"
        For $x = 1 to UBound($arrDims)-1
            $var &= "[" & $arrDims[$x][0] & "]"
        Next
        ConsoleWrite($var & " " & Execute($var) & @CRLF)  ;Output Subscript and Value

        $arrDims[UBound($arrDims)-1][0] += 1   ;Increment Last Dimension Element
        For $y = UBound($arrDims)-2 To 1 Step -1   ;Increment Dimension Element
            If $arrDims[$y+1][0] = $arrDims[$y+1][1] Then
                $arrDims[$y+1][0]=0
                $arrDims[$y][0]+=1
            EndIf
        Next

    Until $arrDims[1][0]=$arrDims[1][1]
    Return ConsoleWrite(@CRLF)
EndFunc

 

Edited by spudw2k
  • Like 1

Share this post


Link to post
Share on other sites
czardas
6 hours ago, spudw2k said:

Neat stuff.  I wasn't clear on what the _PreDim function was doing at first.  It "looked" like a transposition.  I used a fun Dynamic Array Enumerate function I made to visualize and understand it.  I noticed it also "seems" to only support up-to 7 dimensions, leaving the original array unchanged.

Thanks. :) The alpha version I posted a few days ago only worked for up to 7 dimensions. I just ran your test with 9 dimensions (the current limit) and it seems fine.

Trying to visualize multidimensional arrays always used to give me a bit of a headache. I'm sure there's nothing particularly new here, and  It's only through the insights I have gained from others that I came to the choices that I made. It's too early to tell how useful the UDF might be. Two dimensions is enough for most typical applications and there are some really great functions already in Array.au3 (much improved recently by @Melba23).

I'm glad people like it. :thumbsup:

Share this post


Link to post
Share on other sites
spudw2k
1 minute ago, czardas said:

Thanks. :) The alpha version I posted a few days ago only worked for up to 7 dimensions. I just ran your test with 9 dimensions (the current limit) and it seems fine.

Ah, I didn't catch the code update; got it.  Once again, cool stuff.

  • Like 1

Share this post


Link to post
Share on other sites
czardas

This UDF is starting to take shape. I have added three new functions _DeleteDimension(), _ExtractRegion() and _SearchArray(). The example below shows the intended use of all of three functions. This covers a small flexible subset of those features I consider programmatically useful, and particularly relevant to my own projects. Who wants to mess about trying to get all that array syntax right when you can just let a function do most of the tedious work for you?

Fruit Cube

#include <Array.au3>
#include <MsgBoxConstants.au3>
#include 'ArrayWorkshop.au3'

; Example 4 - Fruit Cube [3D Search = cherries]

; create a 3D array of fruit machines
Local $aWheelNum1 = ['strawberry', 'cherries', 'melon', 'pomegranate', 'lemon'] ; 1D array
Local $aWheelNum2 = ['7', 'bell', 'BAR', '$'] ; not so many cherries in this one huh!

Local $aFruitMachine = $aWheelNum1 ; start with a 1D array
For $i = 2 To 5 ; add some more 1D arrays
    _ArrayAttach($aFruitMachine, $aWheelNum2, 2) ; 1D concatenation employed in the 2nd dimension
Next

; it's easier to set indices for each machine to the first dimension
_Predim($aFruitMachine, 3, True) ; convert 2D to 3D - push current dimensions up one level

Local $aFruitCube = $aFruitMachine ; continue cube construction using the 3D array
For $i = 2 To 10 ; add some more fruit machines [10 in total]
    _ArrayAttach($aFruitCube, $aFruitMachine) ; 3D concatenation employed in the 1st dimension
Next

_ShuffleArray($aFruitCube, 0) ; shuffle the array - ignoring dimension bounds to mix things up a little bit

Local $aSearchResults = _SearchArray($aFruitCube, 'cherries') ; search through 1st dimensional indeces [for cherries]
MsgBox($MB_OK, "cherries", UBound($aSearchResults) & ' matches found in 10 fruit machines') ; machines containing cherries

For $i = 0 To UBound($aSearchResults) -1 ; loop through the search results
    $aFruitMachine = _ExtractRegion($aSearchResults, 1, $i) ; extract each machine [3D]
    _DeleteDimension($aFruitMachine, 1) ; delete the 1st dimension for _ArrayDisplay() [no data loss here ==> Ubound($aFruitMachine, 1) = 1]
    _ArrayDisplay($aFruitMachine, 'machine ' & $i +1 & ' contains cherries') ; now we are back to 2D, so we can check everything's working
Next

 

Edited by czardas

Share this post


Link to post
Share on other sites
czardas

New version uploaded - see first post. No new functions - just two bug fixes.

Spoiler

Bugfix 1. _ArrayAttach() hanging with 1D array output. - Fixed
Bugfix 2. _ExtractRegion() hanging with 1D array output. - Fixed

 

Edited by czardas

Share this post


Link to post
Share on other sites
czardas

New function added - _ArraySortXD() -  version 0.2.0-beta (see 1st post). You'll need your waders to get through this one. Because of the complexity, I decided a short tutorial was in order (see below). The function can sort numeric decimal strings of any magnitude. There is only one float which can be larger than a decimal string, and that is infinity. When sorting numeric decimal strings, comparisons are also made between integers and floats.

Like most of the other functions in this thread, _ArraySortXD() works for up to nine dimensions in every sense. You can sort array regions based on item positions within vectors associated with any available dimension. The function aims to be robust and competitive (holding its own against its predecessor), and it is designed to assist in the construction of complex engines requiring multidimensional arrays. Credit is due to the authors of the original _ArraySort() function, and a full list of influential contributors will be added in due course. Have fun!

;============================================================
; _ArraySortXD Tutorial
;============================================================

#include <Array.au3>
#include <MsgBoxConstants.au3>
#include 'ArrayWorkshop.au3'

; Before continuing...
MsgBox($MB_OK, "Important!", "Be sure to read the title on each display.")

;============================================================
; 1. Let's start with 1 dimensional arrays.
;============================================================
Local $aNames = ["corgano", "Rex", "czardas", "trancexx", "iamtheky", "Bowmore", "Chimp", "mikell", "jchd", "argumentum", _
"kcvinu", "Jfish", "spudw2k", "qwert", "soft4pedia", "BrewManNH", "mLipok", "jaberwacky", "Danyfirex", "guinness", "UEZ"]
_ArraySortXD($aNames) ; default algorithm is lexical
_ArrayDisplay($aNames, "1. after sorting")

;============================================================
; 2. Now let's sort the list descending.
;============================================================
_ShuffleArray($aNames) ; mix up the names again
_ArrayDisplay($aNames, "2a. after shuffling")
Local $iAlgo = 1 ; sort descending
_ArraySortXD($aNames, Default, $iAlgo) ; default dimension = 1
_ArrayDisplay($aNames, "2b. reverse sort")

;============================================================
; 3. Sorting a range.
;============================================================
Local $iStart = 5, $iStop = 15
$iAlgo = 0
_ShuffleArray($aNames) ; mix up the names again
_ArraySortXD($aNames, Default, $iAlgo, $iStop, $iStart) ; $iStop and $iStart in the default dimension
_ArrayDisplay($aNames, "3. sort range " & $iStart & " to " & $iStop)

;============================================================
; 4. Sorting numbers lexically.
;============================================================
Local $aIntegers = [10, 2, 9, 300, 64, 123, 100, 20, -5, -23, -19, 801, -5007, -1, -63, -64, -65]
_ArraySortXD($aIntegers) ; lexical sorting
_ArrayDisplay($aIntegers, "4. integers lexical") ; Not exactly what you would expect?

;============================================================
; 5. Sorting numbers numerically.
;============================================================
$iAlgo = 2
_ArraySortXD($aIntegers, Default, $iAlgo) ; numeric sorting
_ArrayDisplay($aIntegers, "5. integers numeric") ; that's more like it!

;============================================================
; 6. Aplhanumeric sort.
;============================================================
_ArrayAttach($aNames, $aIntegers) ; first concatenate names with integers
_ShuffleArray($aNames) ; mix up the data once again
$iAlgo = 4 ; alphanumeric
_ArraySortXD($aNames, Default, $iAlgo) ; alphanumeric sorting
_ArrayDisplay($aNames, "6. alphanumeric")

;============================================================
; 7. Sorting in 2 dimensions.
;============================================================
Local $aAlphaNumeric = _
[['one','two','three','four','five','six','seven','eight','nine','ten'], _
['I','II','III','IV','V','VI','VII','VIII','IX','X'], _
[1,2,3,4,5,6,7,8,9,10], _
['a','b','c','d','e','f','g','h','i','j'], _
['alpha','beta','gamma','delta','epsilon','zeta','eta','theta','iota','kappa'], _
['First','Second','Third','Fourth','Fifth','Sixth','Seventh','Eighth','Ninth','Tenth']]
_ArrayDisplay($aAlphaNumeric, '7a. before sorting')

_ArraySortXD($aAlphaNumeric) ; Sort rows lexically.
_ArrayDisplay($aAlphaNumeric, '7b. default lexical sort on the first column')

Local $iCol = 5
$iAlgo = 1 ; reverse sort
$iStart = 1 ; ignores the first row
$iStop = Default
_ArraySortXD($aAlphaNumeric, Default, $iAlgo, $iStop, $iStart, $iCol) ; Sort on col 5, starting from row 1
_ArrayDisplay($aAlphaNumeric, '7c. reverse sort on column 5 - ignoring the 1st row')

;============================================================
; 8. Sorting in the 2nd dimension.
;============================================================
Local $iDimension = 2 ; instead of sorting rows you can also sort columns
Local $iRow = 4 ; the row to use to sort the columns [1st dimension sub-index]
$iStart = 0 ; starting from the first column
$iStop = 6 ; only sort the first seven columns
$iAlgo = Default
_ArraySortXD($aAlphaNumeric, $iDimension, $iAlgo, $iStop, $iRow, $iStart)
_ArrayDisplay($aAlphaNumeric, '8a. sort the first seven columns on row 4')

$iRow = 2 ; the row to use to sort the columns [1st dimension sub-index]
$iStop = Default ; sort all columns (or rows)
_ArraySortXD($aAlphaNumeric, $iDimension, $iAlgo, $iStop, $iRow, $iStart)
_ArrayDisplay($aAlphaNumeric, '8b. all columns sorted on row 2')

;============================================================
; 9. More advanced numeric sorting.
;============================================================
Local $aDecimals = ['1.000000000000001', '43276590764538761097', '39830476429748701118', '11111111154321098705', '1.0000000000000009999', _
'222222222222222222222', '97611223222222', '890732597342782900543227', '-9', '-0.00000000000000000005', '7023', '300000000000', '8243097852349', _
'56423189049', '76596234001.876485335', '766545374390.0987455323', '820594000000000043', '2313414538342121.0000000654', '-4523', '10000000876655555557', _
'22222222222222222222', '0.000000000000543', '-0.000000000007625', '999999999', '99999998', '-99999998', '200000000', '-1.0', '.0005']
_ArrayDisplay($aDecimals, '9a. randomly typed numeric strings')

$iAlgo = BitOR(2, 256) ; sort numbers and decimal strings
$iDimension = Default ; 1st dimension
_ArraySortXD($aDecimals, $iDimension, $iAlgo)
_ArrayDisplay($aDecimals, '9b. numeric strings sorted by magnitude')

Local $aMoreNumbers = [(1/3)*10^20, 1/0, 1.23456789^200, -1/0, 1.94447653276963*10^-70, -1^.5, 1.0e-16, 13^6]
_ArrayAttach($aMoreNumbers, $aDecimals) ; concatenate
_ShuffleArray($aMoreNumbers)
_ArrayDisplay($aMoreNumbers, '9c. mixed numeric data types')

_ArraySortXD($aMoreNumbers, $iDimension, $iAlgo)
_ArrayDisplay($aMoreNumbers, '9d. mixed numeric data sorted')

;============================================================
; 10. Maintain original sequence for non-sorted items.
;============================================================
$iAlgo = BitOR(1, 2, 256, 512) ; descending, numeric, include decimal strings and maintain the original sequence for unsorted items
_ArrayAttach($aNames, $aMoreNumbers) ; concatenate ($aNames was sorted ascending earlier)
_ArrayDisplay($aNames, '10a. before numeric descending')

_ArraySortXD($aNames, $iDimension, $iAlgo)
_ArrayDisplay($aNames, '10b. unsorted items appear in the original sequence')

 

Edited by czardas

Share this post


Link to post
Share on other sites
iamtheky

Can you show me an example where

1)  you have a 4x4 3D cube

2) you sort the 3x3 cube inside the 4x4, leaving the 'outside' jumbled while the inside is sorted. 

(I know this sounds eerily similar to one of your super secret scripts, but shhh they will never know)

I think that will give me the best picture of a '3D range sort'.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
czardas

I'm not quite sure what you mean by a 4x4 3D cube. Let's think of it like this: you have some cubes joined together in the fourth dimension. Let's say the first item in each cube is some kind of identifier positioned at element [X][0][0][0]. You can sort the cubes on the value of their identifiers within the range x = 1 To x = 10. Alternatively x could be in a different dimension and the identifier at another location like this: [2][3][x][8]. Does that make any sense?

Read the description in the function header and try sorting tables in 3D, or something not too complicated to figure it out. Then you can try for higher dimensions. I'll add some 3D/4D examples shortly. Not right now, I'm completely bushed after writing that.

Edited by czardas

Share this post


Link to post
Share on other sites
iamtheky

http://www.ebay.com/itm/like/161187154878?lpid=82&chn=ps&ul_noapp=true

 

now if even the ones on the inside of the rubiks cube had stickers: could you sort those sides and leave the outside jumbled?

(and i guess it a 2 sided cube that resides on the inside of a 4sided  cube..)

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
czardas

@iamtheky There are some functions yet to be included in this UDF. They will enable you to peel away the outer layer to get at the 3D core. The array could later be reconstructed using _ArrayAttach(). Perhaps not the most direct solution, but stripping functions are far simpler to write.

Share this post


Link to post
Share on other sites
czardas

As promised: an example of sorting the contents of a 3D array. I hadn't tested more than two dimensions when I posted version 0.2.0-beta yesterday, and I was a bit worried it might not work. Thank goodness it did. :sweating: I have tried to make this an easy example.

Example: Foul Play in the English Premiership

#include <Array.au3>
#include <ArrayWorkshop.au3>

; stats for the English premiership home games 2014-2015
Local $aHomeGames = [["","Fouls","Yellow Cards","Red Cards"],["Arsenal",179,27,1],["Aston Villa",191,28,4],["Burnley",212,33,0], _
["Chelsea",200,36,1],["Crystal Palace",270,26,2],["Everton",185,27,0],["Hull",229,28,3],["Leicester",225,20,2],["Liverpool",190,29,2], _
["Man City",234,35,1],["Man United",223,31,1],["Newcastle",208,33,1],["QPR",222,36,1],["Southampton",232,23,2],["Stoke",240,33,0], _
["Sunderland",218,45,1],["Swansea",195,25,1],["Tottenham",219,37,1],["West Brom",197,34,1],["West Ham",204,33,1]]
_ArrayDisplay($aHomeGames, 'Home Games')

; stats for the English premiership away games 2014-2015
Local $aAwayGames = [["","Fouls","Yellow Cards","Red Cards"],["Arsenal",218,36,2],["Aston Villa",205,41,2],["Burnley",203,34,0], _
["Chelsea",223,42,3],["Crystal Palace",234,35,1],["Everton",233,40,3],["Hull",228,34,4],["Leicester",176,28,5],["Liverpool",255,43,2], _
["Man City",144,34,3],["Man United",223,42,2],["Newcastle",231,55,0],["QPR",216,28,1],["Southampton",197,30,2],["Stoke",221,34,2], _
["Sunderland",243,38,2],["Swansea",246,52,2],["Tottenham",187,37,1],["West Brom",219,26,2],["West Ham",247,36,6]]
_ArrayDisplay($aAwayGames, 'Away Games')

; now let's make this a 3D cuboid
Local $aCuboid = $aHomeGames ; create a 2D template
_ArrayAttach($aCuboid, $aHomeGames, 3) ; stack tables [3D]
_ArrayAttach($aCuboid, $aAwayGames, 3) ; ditto

; calculate the total number of fouls, yellow cards and red cards for games played home and away
For $i = 1 To UBound($aCuboid) -1 ; loop through the teams
    For $j = 1 To 3 ; [fouls, yellow cards, red cards]
        $aCuboid[$i][$j][0] = $aCuboid[$i][$j][1] + $aCuboid[$i][$j][2] ; add two values from each 3D region
    Next
Next

; THE (VERY FIRST) 3D TEST
; sort the 3D array from the highest to the lowest number of fouls (home and away)
_ArraySortXD($aCuboid, 1, 2+1, -1, 1, 1) ; this is just an example

; let's check to see if _ArraySortXD actually works [^^]
; because we stacked the tables in a certain way, we can delete the 3rd dimension and check the result with _ArrayDisplay
_DeleteDimension($aCuboid, 3) ; other methods can also be used to check the contents of the first table in the 3D stack
_ArrayDisplay($aCuboid, 'Dirtiest Premiership Team in 2015')

Regarding the suggestion by @iamtheky above, the complication of limiting array regions in every dimension would involve additional stop parameters (for up to nine dimensions) and have a negative impact on speed. It's actually more complicated than that. Nice idea though!

Edited by czardas
  • Like 1

Share this post


Link to post
Share on other sites
iamtheky

That is a clean example too, gives me hope for understanding the workshop!

  • Like 1

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
stealthmsgr

Thanks millions czardas for posting this on arrays. I'm new into the array area and this should prove to be a great learning tool. I have a small project that I'm working on if you could take a look and let me know how to solve it. I believe an array would be best. As a newbie into arrays perhaps you could give me some pointers. I'll give you some detail if you have time to look it over.

 

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • Iceburg
      By Iceburg
      Hi everyone, I'm at best a noobie.  I have read through the Array helps, and specifically the 2D array help file, and I'm struggling to get my code working.
      I have an array that is read from a file, thats working great.  I'm trying to do some math on the array, so I can find the largest, average, lowest, day over day change %, etc.
      The array read working fine, I get 43 lines, line 0 is 44, and then I get data that looks like
      0519 $10,000
      0520 $10,001
      0521 $10,002
      The data in this array is a single 1D array, breaking it out into 2 columns so I can do the math is what I can get to happen.  
      How do I reference the array to store this data?  Second, how do I assign this data to the appropriate row/column?
      Thanks in advance.
      Dim $all_cash_amounts[UBound($aInput)][2] Dim $max_amount_in_account Dim $min_amount_in_account _FileReadToArray($LC_Check_file_path, $aInput) _ArrayDisplay($aInput) local $date = StringRegExp($aInput[1], "(\d\d\d\d)", 1) local $cash = StringRegExp($aInput[1], "\d+\s(-?[0-9\.\,]+)", 1) ConsoleWrite("Date is: " & $date & @CRLF) For $i = 1 To UBound($aInput)-1     $date = StringRegExp($aInput[$i], "(\d\d\d\d)", 1)     $all_cash_amounts[$i][2] = $date[$i][0], $cash[$i][1]      Next _ArrayDisplay($all_cash_amounts)  
    • OldGuyWalking
      By OldGuyWalking
      Given an array with multiple columns that is displayed in a listview,
       ===> What is the fastest/most efficient way to create and manage multiple filters and display results in ListView.
      I have a text file that loads into a listview that has string, numeric, and date columns.  The main file contains about 5100 rows. It's loaded into an array and (in this ListView) it's pre-filtered to display a range of rows based on a start and end date.  On the form I have menu options for various filters. (see below).
      I have options to filter on an "Air Date" column (=Today, >=Today, <=Today) and on a numeric field that is either 1 or 0 that indicate Active or Ended.

      For each filter option I have a prebuilt array that holds a subset of the main array based on a single filter.  For the list above I have the main Array and 5 additional arrays.  None of the arrays are updated since this is for "view only" purposes.  This is a short list and I could have done the filtering "live" but I have several of these forms and so kept the same functionality in each. I have another ListView that displays the complete 5100 row list with 3 filters that, when building the filters live was considerably slower than using prebuilt arrays.
      If I want to expand past simple single column filtering, using an array for each filter becomes cumbersome especially if I want to combine filters using AND & OR.
      The text file I'm working with has 16 columns. If I setup filters for 4 columns and include AND / OR capability that would require prebuilding 24 arrays to cover the various combinations.
      If using the slower method of building a filtered array in real time each time a different filter is selected is the only way to go with this then I'll live with it. It is less overhead. .
      Below is the code I'm currently using to "filter" an array.  My next change was going to add AND / OR functionality (see the info above the header for where I was going with this) .
      ; Description ...: Delete rows from an array and only keep rows that meet the crtieria of identified columns. ; ; Next Change: Add AND/OR to combine filters. Use array to hold multiple criteria and values? ; ; Local $aCriteria[][] = [["",$iColNbr1, $sOperator1, $vValue1], ["AND",$iColNbr2, $sOperator2, $vValue2], ["OR",$iColNbr3, $sOperator3, $vValue3]] ; The first set of criteria ["", $iColNbr1, $sOperator1, $vValue1] must start with a "". ; If anything is entered in that first parameter it will be ignored. ; If the first parameter in any additional criteria set is left blank, or it is not OR, it will default to AND. ; If $aArray is 1 dimension with more than one set of criteria, only the first set will be used. ; Any criteria that uses a column that is less than 0 or higher than the total number of columns in the array will return an error. ; ; Recognized data types for this function are: S (String), D (Date), N (Number). ; ; Recognized Operators are: "EQ", "NEQ", "IN", "GT", "GE", "LT", "LE", "BETWEEN". ; ****** Not all operators work with all data types. ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ArrayFilter ; Description ...: Delete rows from an array and only keep rows that meet the crtieria of identified columns. ; Syntax ........: _ArrayFilter(Byref $aArray[, $iCol = 0[, $sOperator = "EQ"[, $vValue = ""[, $iOptionBase = 0]]]]) ; Parameters ....: $aArray - Array being filtered. ; $iCol - [optional] Column to filter. Default is 0. ; $sOperator - [optional] Operator. Default is "EQ". ; $vValue - [optional] Criteria to compare the column/row value against. ; $iOptionBase - [optional] Starting row. Default is 0. ; Return values .: None ; Author ........: OldGuyWalking ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _ArrayFilter(ByRef $aArray, $iCol = 0, $sOperator = "EQ", $vValue = "", $iOptionBase = 0) Local $hFunc = _ArrayFilter $vValue = StringStripWS($vValue, 3) If $vValue = "[Today]" Then $vValue = _NowCalcDate() EndIf Local $sMsg Local $sMsgHdr Local $n1 Local $sDeleteIndex Local $aDeleteIndex Local $iCnt = 0 Local $iRows Local $iColMax Local $iDim Local $sData Local $sVType Local $sDType Local $LBound Local $iDiff If $iOptionBase <> 0 Then $iOptionBase = 1 EndIf If _IsValueEmpty($aArray) Then Return SetError(1, 0, "") EndIf $iDim = UBound($aArray, $UBOUND_DIMENSIONS) If $iDim = 1 Then If $iCol <> 0 Then $iCol = 0 EndIf EndIf If $iDim = 2 Then $iColMax = UBound($aArray, $UBOUND_COLUMNS) - 1 If $iCol > $iColMax Or $iCol < 0 Then Return SetError(1, 0, "") EndIf EndIf If Not _IsBetween($iDim, 1, 2) Then ;############### MSG2 - START ############### $sMsgHdr = FuncName($hFunc) & " :Line: " & @ScriptLineNumber & " :Error= " & @error $sMsg = "Invalid Dimensioned Array. Must be a 1 or 2 dimensional array." MsgBox(0, $sMsgHdr, $sMsg) Return SetError(1, 0, "") ;############### MSG2 - END ############### EndIf ; Identify what the value is ; If it is not a String, Int, Number, or Date then skip. Select Case _DateIsValid($vValue) = 1 $sVType = "D" Case IsNumber($vValue) = 1 $sVType = "N" Case IsString($vValue) = 1 $sVType = "S" Case Else ;############### MSG2 - START ############### $sMsgHdr = FuncName($hFunc) & " :Line: " & @ScriptLineNumber & " :Error= " & @error $sMsg = "Comparison value must be a " & @CRLF & _ "1. Date in YYYY/MM/DD format " & @CRLF & _ "2. A string " & @CRLF & _ "3. A number " & @CRLF MsgBox(0, $sMsgHdr, $sMsg) Return SetError(1, 0, "") ;############### MSG2 - END ############### EndSelect $iCnt = 0 For $n1 = UBound($aArray) - 1 To $iOptionBase Step -1 If $iDim = 1 Then $sData = StringStripWS($aArray[$n1], 3) ElseIf $iDim = 2 Then $sData = StringStripWS($aArray[$n1][$iCol], 3) EndIf Select Case _DateIsValid($sData) = 1 $sDType = "D" Case IsNumber($sData) = 1 $sDType = "N" Case IsString($sData) = 1 $sDType = "S" Case Else $sDType = "U" EndSelect If _IsValueEmpty($sData) Then $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop ; $sDType = $sVType EndIf If Not _IsValueEmpty($sData) And $sDType <> $sVType Then $sDeleteIndex = $sDeleteIndex & $n1 & "," $iCnt += 1 ContinueLoop EndIf Select Case $sOperator = "EQ" Switch $sDType Case "D" $iDiff = _DateDiff("D", $vValue, $sData) If $iDiff = 0 Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "S" If $sData = $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "N" If $sData = $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "NEQ" Switch $sDType Case "D" If $sData <> $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "S" If $sData <> $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "N" If $sData <> $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "IN" Switch $sDType Case "S" If StringInStr($sData, $vValue) Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "GT" Switch $sDType Case "N" If $sData > $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "D" $iDiff = _DateDiff("D", $vValue, $sData) If $iDiff > 0 Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "GE" Switch $sDType Case "N" If $sData >= $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "D" $iDiff = _DateDiff("D", $vValue, $sData) If $iDiff >= 0 Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "LT" Switch $sDType Case "N" If $sData < $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "D" $iDiff = _DateDiff("D", $vValue, $sData) If $iDiff < 0 Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch Case $sOperator = "LE" Switch $sDType Case "N" If $sData <= $vValue Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop Case "D" $iDiff = _DateDiff("D", $vValue, $sData) If $iDiff <= 0 Then ContinueLoop EndIf $sDeleteIndex &= $n1 & "," $iCnt += 1 ContinueLoop EndSwitch EndSelect Next If $iCnt > 0 Then _DeleteArrayRows($aArray, $sDeleteIndex) EndIf EndFunc ;==>_ArrayFilter Thanks in advance.
      OldGuyWalking
    • MyEarth
      By MyEarth
      Hello. I have a 1D array. Is made in this way:
      1. This is a line Messages: a message etc Context: a context etc 2. This is a line Messages: a message etc Context: a context etc 3. This is a line Messages: a message etc Correction: a correction etc Context: a context etc I need to make something like:
      1. This is a line|Messages: a message etc|Context: a context etc 2. This is a line|Messages: a message etc|Context: a context etc 3. This is a line|Messages: a message etc|Correction: a correction|Context: a context etc For exporting in another software. I need to split every time there is a number when the line start, can be 1. until something like 3.976. Since i don't know if there a 2 line after a number or 3 i have opened this thread. Thanks
    • FMS
      By FMS
      Hello,
      The last couple of day's I was searching on this forum for the best way to put array's inside array's.
      The best example's i found where a little outdatet (2010) whit a lot of pro's and con's.
      Now I've a big script where a lot of computations and big array's are involved, so speed is a big issue.
      Also I wanna try the script below but don't know iff speed is a problem this way or maybe there is a better way to do this.

      Does somebody know's the best way to put array's inside array's and get the data back from them?
      I've made an example of something I was thinking about.
      (maybe something totaly wrong but I'm open for sugestions)
      I'm doing it this way because I don't think I can access the data inside the array (and doing some calculations to it) some other way if the array is inside another array.
      Or is there?
      Thanks in advanced.
      #include <Array.au3> Global $aArray[Random(5,10,1)][Random(5,10,1)] Global $Holder[2][2] For $x = 0 To UBound($aArray,1) - 1 For $y = 0 To UBound($aArray,2) - 1 $aArray[$x][$y] = Round(Random(-1,1),4) Next Next $Holder[0][0] = $aArray $aArray = "" Global $get_array = $Holder[0][0] _ArrayDisplay($get_array)  
    • FMS
      By FMS
      Hello,
      I'm trying to randomly change some cells in a array on a given percentage.
      at this point I 've a array whit all 0's and want to change some cells to 1.
      I'm not shure how to do this in a good coding sort of way.
      Also maybe there is a build in function whish I'm not aware of.
      Does somebody know how I can do this in a easy way?
      I was trying to get the total count of cells and get the percentage of it.
      And was stuck when i wanna change the cell.
      please advice, thanks in advanced for your help.
      #include <Array.au3> Global $percentage = 0.2 Global $aArray[Random(10,30,1)][Random(10,30,1)] For $x = 0 To UBound($aArray,1) - 1 For $y = 0 To UBound($aArray,2) - 1 $aArray[$x][$y] = 0 Next Next _ArrayDisplay($aArray) randomize() _ArrayDisplay($aArray) Func randomize() Local $total_to_change = ((UBound($aArray,1) * UBound($aArray,2)) / 100) * $percentage ConsoleWrite( "$total_to_change = " & $total_to_change & @LF ) ConsoleWrite( "total in array = " & (UBound($aArray,1) * UBound($aArray,2)) & @LF ) EndFunc  
×