Jump to content

Array Handling


Spiff59
 Share

Recommended Posts

Global $Patient_Array[8000][12]
Global $Patient_record[12]
Global $Current_Patient

$Current_Patient = 1234
$Patient_Record = $Patient_Array[$Current_Patient]; <-- errors with "incorrect number of subscripts"

In some earlier scripts I gave up on trying to reference an entire record/row out of a 1D or 2D array, since leaving off the last index caused syntax errors. Instead, I just went the manual route and used fully-qualified data names and seperate statements to process each column. This array has 12 columns in each row, and I could save a lot of code if I could manipulate those 12 fields around in one chunk. It would be sweet if the above assignment statement was valid.

_ArrayDelete allows one to reference an entire row...

Anyone have any ideas besides referencing each field?

I'm guessing adding this capability to Autoit has been discussed in the past?

Thanks.

Link to comment
Share on other sites

Global $Patient_Array[8000][12]
Global $Patient_record[12]
Global $Current_Patient

$Current_Patient = 1234
$Patient_Record = $Patient_Array[$Current_Patient]; <-- errors with "incorrect number of subscripts"

In some earlier scripts I gave up on trying to reference an entire record/row out of a 1D or 2D array, since leaving off the last index caused syntax errors. Instead, I just went the manual route and used fully-qualified data names and seperate statements to process each column. This array has 12 columns in each row, and I could save a lot of code if I could manipulate those 12 fields around in one chunk. It would be sweet if the above assignment statement was valid.

_ArrayDelete allows one to reference an entire row...

Anyone have any ideas besides referencing each field?

I'm guessing adding this capability to Autoit has been discussed in the past?

Thanks.

No. AutoIt doesn't work that way and won't for the foreseeable future. _ArrayDelete() does not work that way either. If you open the UDF you will see it tests if the array is 1D or 2D and runs different code with appropriate number of indexes, as you will have to in order to create the functionality you want.

2D arrays are very useful, I use them often. They require correct syntax like anything else.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Show us what data your trying to save... then we can help... or try it with a smaller array

#include <array.au3>
dim $Patient_Array[100][12]

$Patient_Array[55][1]="name"
$Patient_Array[55][2]="Address line1"
$Patient_Array[55][3]="Address line2"
_arraydisplay($Patient_Array)
Link to comment
Share on other sites

I recall that in both C and COBOL one could group individual fields and manipulate them as a whole. I'm sure behind the scenes the compiler was generating code to move the fields seperately, but at the application level I didn't have to mess with it.

I tried getting sneaky with the following, but it didn't fly either:

#include <Array.au3> 
Dim $BigArray[1000]
Dim $array[4] = ["A","BB","CCCC","DDDD"]
$BigArray[0] = $array
_ArrayInsert($BigArray, 1, $array)
_ArrayDisplay($BigArray)

I'll reference the fields individually. I just wanted to make sure I wasn't missing out on some shortcut.

Link to comment
Share on other sites

This won't work either because the kind of assignment is not supported.

You can for example send a whole array variable to a function using only it's name without any specification of subscripts but passing array reference to an array's subscript is invalid in AutoIt as far as I know, and ReDimming an array with different element invalidate the content of the subscripts which aren't overlapping the already used array.

Maybe code can help better than my words:

#include <Array.au3>
Dim $Arr[5][2], $i, $j

For $i = 0 To 4
    For $j = 0 To 1
        $Arr[$i][$j] = 1
    Next
Next

_ArrayDisplay($Arr, 'OK, everything is fine and as expected')

ReDim $Arr[2][5] ; Now only values $Arr[0][0] to (include) $Arr[1][1] are now valid, anything else is undefined or 0

_ArrayDisplay($Arr, 'Array display after ReDim')

What you might want is to use some sort of counters mechanism which will never exceed the array's last row/col range, or, some sort of function that achieve the desire effect of one long single dimension array, though I see no place for such a function in this cases right now.

Link to comment
Share on other sites

I was just hoping there was a way to reference a 2D array with a single subscript thereby accessing all the columns in that row at once. Were the array a file, it would be akin to reading a record, containing multiple fields, from the file.

The functionality of my first non-working example is what I'd hoped for. Example 2 was just a shot in the dark, a second example of what I'm wanting, I didn't expect the assignment to convert pointers and insert all the data, basically making my 1D array into a 2D array.

I could split my 2D array into a bunch of huge 1D arrays, or go with one huge 1D array by stringing all my fields (or columns) together with delimiters and then splitting them back out once read, but those are as big, or bigger, violations of the KISS rule than just referencing each column seperately.

Maybe some future enhancement would allow one to define "$File Array[1000][12]" and "$RecordArray[12]" and you could say "$RecordArray = $FileArray[234]" after which a "Tooltip($RecordArray[3])" might display "Record235-Field4".

Edited by Spiff59
Link to comment
Share on other sites

a Kiss example

#include <array.au3>
dim $Patient_Array[100][12]

$Patient_Array[55][1]="name"
$Patient_Array[55][2]="Address line1"
$Patient_Array[55][3]="Address line2"
$res=""
For $x=1 to 11
    $res&=$Patient_Array[55][$x]&" "
Next
MsgBox(0,"KISS",$res,0)
MsgBox(0,"Or KISS",$Patient_Array[55][2],0)
Link to comment
Share on other sites

I was just hoping there was a way to reference a 2D array with a single subscript thereby accessing all the columns in that row at once. Were the array a file, it would be akin to reading a record, containing multiple fields, from the file.

And how would that work with 3D array, or 4D? What if the first index is column and the second index is row, since those are arbitrary designations in usage? You are making to many limited assumptions about arrays in general. The basic array addressing of AutoIt accommodates many more data types than your limited examples. For needs specific to your usage, there are stock and custom UDFs.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Do you have to use a 2D array? I have written several large programs for work, which do mass 2D database work, but using only a 1D array.

Like this:

#include <Array.au3>

;----- Database is President|Start|Finish -----
Global $aArray[6]
$aArray[1] = "George Washington|1789|1797"
$aArray[2] = "John Adams|1797|1801"
$aArray[3] = "Thomas Jefferson|1801|1809"
$aArray[4] = "James Madison|1809|1817"
$aArray[5] = "James Monroe|1817|1825"

;----- Display each row as array -----
For $i = 1 to (UBound($aArray) - 1)
    $aData = StringSplit($aArray[$i],"|")
    _ArrayDisplay($aData)
Next

..... each time you need access to individual 'columns', simply StringSplit to a temporary array ($aData).

In fact I wrote this UDF to help sort data using this technique.

[EDIT]

I could split my 2D array into a bunch of huge 1D arrays, or go with one huge 1D array by stringing all my fields (or columns) together with delimiters and then splitting them back out once read, but those are as big, or bigger, violations of the KISS rule than just referencing each column seperately.

oops, I'll read through properly next time. promise. Edited by andybiochem
- 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

And how would that work with 3D array, or 4D? What if the first index is column and the second index is row, since those are arbitrary designations in usage? You are making to many limited assumptions about arrays in general. The basic array addressing of AutoIt accommodates many more data types than your limited examples. For needs specific to your usage, there are stock and custom UDFs.

It would work the same way regardless of how many dimensions were defined, or of what name anyone wants to refer to a particular dimension by. Logically, the fourth, or twenty-fourth, occurance of a higher-level subscript "contains" the fourth, or twenty-fourth, occurances of all the elements in the next lower dimension. I just asked if there were a way to refer to those groups in that manner. It's something I would have found convenient in a number of scripts.

I suppose something like below, that pulls a "record" out of a 2D array and into a 1D array, but written in lower-level code was what I was thinking of.

Global $TeamArray[6][3] = [ ["Joe", "Shortstop", 34],["Dave", "Pitcher",    12],["Marty", "Left Field", 41], _
                        ["Bob", "Catcher",   22],["Bill", "Third Base", 51],["Frank", "First Base",  4]]
Global $PlayerArray[3]

$PlayerArray = _ArrayExtract($TeamArray, 3, $PlayerArray)
Msgbox(1,"", $PlayerArray[0] & " plays " & $PlayerArray[1] & " and wears number " & $PlayerArray[2])
Exit


;-------------------------------------------------------------------------------
Func _ArrayExtract(ByRef $avArraySource, $iElement, $avArrayTarget)
    If Not IsArray($avArraySource) Then Return SetError(1, 0, 0)
    If Not IsArray($avArrayTarget) Then Return SetError(1, 0, 0)
    If Not UBound($avArraySource, 0) = 2 Then Return SetError(2, 0, 0); Source is 2D
    If Not UBound($avArrayTarget, 0) = 1 Then Return SetError(2, 0, 0); Target is 1D
    
    Local $iUBoundSource = UBound($avArraySource, 1)
    If $iElement < 0 Then $iElement = 0
    If $iElement > $iUBoundSource Then $iElement = $iUBoundSource
    
    Local $iUBoundTarget = UBound($avArrayTarget, 1)
    If Not UBound($avArraySource, 2) = $iUBoundTarget Then Return SetError(3, 0, 0); Number of elements differ

    For $i = 0 to $iUBoundTarget - 1
        $avArrayTarget[$i] = $avArraySource[$iElement][$i]
    Next
        
    Return $avArrayTarget
EndFunc ;==>_ArrayExtract

EDIT: Version 2 -Don't pass the target array (third parameter) to the function. Instead, in the function, just check the UBound of the second dimension of the source array, dimension a local array based off of that, then return that temporary array back to the caller.

Edited by Spiff59
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...