5. Arrays and Structures


Introduction

An array is data in which many values are associated with the same variable name, but each value has its own 'subscript' or 'index value' to distinguish it from the others. Data stored in this way is much easier for a program to manage than data stored in completely unrelated variable names.

Arrays in Miva are fully multi-dimensional (up to the limits of the system). They grow dynamically, meaning that if a previously unused array position is accessed, a new entry will be created. This mirrors the way standard Miva variables work.

Structures are name based collections of variables. By themselves, they have no value.

Arrays

Evaluation

Array elements can be accessed by specifying an array index in square brackets.

Syntax:

<MvEVAL EXPR = "{ l.array[ 100 ] }">
<MvEVAL EXPR = "{ l.array[ 1 ][ 2 ][ 1 ] }">

The value inside the square brackets may be an expression, but the results will be converted to the nearest integer (consistent with existing expression evaluation and "atoi" functionality):

<MvEVAL EXPR="{ l.array[ l.pos ] }"><!-- ok -->
<MvEVAL EXPR="{ l.array[ 'Test' ] }"><!-- runtime error -->
<MvEVAL EXPR="{ l.array[ 3.15 ] }"><!-- equal to [3] -->
<MvEVAL EXPR="{ l.array[ 'm' + 3 ] }"><!-- equal to [3] -->

Arrays are 1-based.

If an array is evaluated with no specified index, Miva will return a string in the format "value,value...", with sub-arrays at a particular index being displayed as a value delimited by parenthesis.

Example:

"one,two,(value at [3][1],value at [3][4]),four"

Assignment

If a value is assigned to an array without specifying an index, the array will be destroyed and the variable will revert to a simple variable. Likewise, if a value is assigned to an element that previously contained more dimensions, the values in the extra dimensions will be destroyed and replaced with the single value.

Array Index

An array index can be either a constant array index or a variable array index.

Multiple Dimension Arrays

<MvASSIGNARRAY> defines a multi-dimension array.

Syntax:

<MvASSIGNARRAY NAME="l.array" VALUE="123">
<MvDIMENSION INDEX="1">
<MvDIMENSION INDEX="2">
<MvDIMENSION INDEX="7">
</MvASSIGNARRAY>
The above assignment would be accessed in an expression as "l.array[1][2][7]"
Error Conditions
There are no Miva tags other than MvDIMENSION or MvMEMBER tags allowed between <MvASSIGNARRAY> and </MvASSIGNARRAY> tags.

Structures

Structures are name based collections of variables. A structure is automatically created when a variable is referenced using the MEMBER attribute:

<MvASSIGN NAME="l.structure" MEMBER="member" VALUE = "1">

Other methods of referring to a structure are:

<MvASSIGN NAME="l.structure" MEMBER="member:submember" VALUE="2">

If a value is assigned to a member that did not previously exist, then that member will be created.

Structures, in and of themselves, have no value. However, when used in an expression without member qualification, Miva will return the data from the structure in a string in the format of "value[,value...]", with sub-structures at a particular index being displayed as a 'value' delimited by parenthesis.

Example:

"one,two,(value at m3:a,value at m3:b),four"

Structures and arrays may be passed as parameters to functions if the function parameter is declared as called by reference (i.e., with the VAR keyword after the variable name in the function definition). Without the VAR keyword, the structure or array is copied, and changes will not be seen by the calling program.

Using Arrays and Structures Together

The MvASSIGN tag will take both an INDEX and a MEMBER attribute. The array index will take precedence over member attribute when INDEX and MEMBER are used explicitly.

Examples:

<MvASSIGN NAME="varname" MEMBER="membername" INDEX="3" VALUE="valuevvv">

Results in an array of structures, and the expression "{varname[3]:membername eq 'valuevvv'}" would return true.

<MvASSIGNARRAY NAME="varname" VALUE="valuevvv">
<MvDIMENSION INDEX="4">
<MvDIMENSION INDEX="5">
<MvDIMENSION INDEX="6">
</MvASSIGNARRAY>

Results in a multiple dimension array of structures, and the expression "{varname[4][5][6] eq 'valuevvv'}" would return true.

To override the index precedence, use the ":" operator in the NAME to signify that the member name is first.

Example:

<MvASSIGN NAME="varname:membername" INDEX="3" VALUE="valuevvv">

Results in a structure with an array in the member, and "{varname:membername[3] eq 'valuevvv'}" would evaluate as true.

Example:

<MvASSIGNARRAY NAME="varname" VALUE="valuevvv">
<MvDIMENSION INDEX="4">
<MvMEMBER NAME="five">
<MvDIMENSION INDEX="6">
</MvASSIGNARRAY>

The above assignment would be accessed in an expression as "varname[4]:five[6]".

If a member name is used in a place where an array assignment was previously made (or visa versa), that array is destroyed.

Example:

<MvASSIGN NAME="l.var" INDEX="3" VALUE="onevalue">
<MvASSIGN NAME="l.var" INDEX="4" VALUE="anothervalue">
<MvASSIGN NAME="l.var" MEMBER="something" VALUE="anothervalue">

The array values are destroyed by the member assignment.

Also, using MvASSIGN and MvASSIGNARRAY, sub-array and sub-structure references and assignments will work.

Example:

<MvASSIGNARRAY NAME="l.var" VALUE="value1">
<MvDIMENSION INDEX="3">
<MvDIMENSION INDEX="4">
</MvASSIGNARRAY>
<MvASSIGNARRAY NAME="l.var" VALUE="value2">
<MvDIMENSION INDEX="3">
<MvDIMENSION INDEX="5">
</MvASSIGNARRAY>
<MvASSIGN NAME="l.var2" value="l.var[3]">

The variable l.var2 will be an array with values at [4] and [5].

Multiple Form Variables with the Same Name

When a Miva script is the target of a FORM's ACTION, the variable can still be referenced without qualifier to get a comma-separated list of the multiple responses.

The variable can now be addressed as a one-based array, with each of the values occupying one element.

Example:

<MvIF EXPR="{commalist ne ''}">

<MvASSIGN NAME="expected" INDEX="1" VALUE="value 1">

<MvASSIGN name="EXPECTED" index="2" value="value 2">

<MvASSIGN name="EXPECTED" index="3" value="value 3">

<MvASSIGN name="EXPECTED" index="4" value="value 4">

<MvASSIGN name="EXPECTED" index="5" value="value 5">

<MvASSIGN name="EXPECTED" index="6" value="value 6">

<MvASSIGN name="EXPECTED" index="7" value="value 7">

<MvASSIGN NAME="l.success" VALUE="1">

<MvASSIGN NAME="l.count" VALUE="{1}">

<MvASSIGN NAME="l.max" VALUE="{miva_array_max(commalist)}">

<MvWHILE EXPR="{l.count le l.max}">

<MvIF EXPR="{commalist[count] ne expected[count]}">
<MvEVAL EXPR="{'failed at ' $ count $ ', expected '
$ expected[count] $ ', got' $ commalist[count]}">
<MvASSIGN NAME="l.success" value="0">
</MvIF>
<MvASSIGN NAME="count" VALUE="{count + 1}">

</MvWHILE>

<MvIF EXPR="{l.success eq 0}">

Failed

<MvELSE>

Succeed

</MvIF>

<MvELSE>

Please press the button below to start the AddFormVariable test

</MvIF>

<form>

<input name="commalist" value="value 1" type="hidden">

<input name="commalist" value="value 2" type="hidden">

<input name="commalist" value="value 3" type="hidden">

<input name="commalist" value="value 4" type="hidden">

<input name="commalist" value="value 5" type="hidden">

<input name="commalist" value="value 6" type="hidden">

<input name="commalist" value="value 7" type="hidden">

<input SIZE="10" value="Start Test" type="submit">

</form>