Arrays & Structures#
Arrays and structures are used to store multiple values in a single variable. They can consist of a simple indexed list of values or more complex spreadsheet- or database-like structures.
Important
In Miva Script, an array index must be a positive integer. An array index of 0 or lower will cause a runtime error.
Miva Script provides two tags, <MvASSIGN>
and <MvASSIGNARRAY>
, that are functionally identical. For most uses, the former is used; for complex multi-dimensional arrays or structures, the latter often makes the script more readable.
When passing arrays as parameters in a user-defined <MvFUNCTION>
, it is more efficient to declare the parameter with the VAR
keyword, passing the array by reference rather than passing a copy. This also allows you to directly alter the array within the function rather than altering the copy and returning it with <MvFUNCTIONRETURN>
.
Simple Structures#
This example shows a simple structured variable where each member is an attribute of the variable.
<MvASSIGN NAME="g.Month" MEMBER="Name" VALUE="January">
<MvASSIGN NAME="g.Month" MEMBER="Abr" VALUE="Jan">
<MvASSIGN NAME="g.Month" MEMBER="Num" VALUE="1">
Month: <MvEVAL EXPR="{ g.Month:Name }"> Abbreviation: <MvEVAL EXPR="{ g.Month:Abr }"> <br>
<!-- Alternate syntax: -->
<MvASSIGN NAME="g.Month:Name" VALUE="January">
Simple Arrays#
These examples show arrays with the index first as a literal number, then as a variable. They also create two arrays to contain different but related data.
<MvASSIGN NAME="g.Month_Name" INDEX="1" VALUE="January">
<MvASSIGN NAME="g.Month_Name" INDEX="2" VALUE="February">
<MvASSIGN NAME="g.Month_Name" INDEX="3" VALUE="March">
<MvASSIGN NAME="g.Month_Abr" INDEX="{ g.first }" VALUE="Jan">
<MvASSIGN NAME="g.Month_Abr" INDEX="{ g.first + 1 }" VALUE="Feb">
<MvASSIGN NAME="g.Month_Abr" INDEX="{ g.first + 2 }" VALUE="Mar">
Month: <MvEVAL EXPR="{ g.Month_Name[1] }">. Abbreviation: <MvEVAL EXPR="{ g.Month_Abr[1] }"> <br>
Array Structures#
Array structures can represent more complex data. This example joins the two arrays above into a single structure stored in the variable g.Month
, where each index is like a row and each member a named column.
<MvASSIGN NAME="g.Month" INDEX="1" MEMBER="name" VALUE="January">
<MvASSIGN NAME="g.Month" INDEX="1" MEMBER="abr" VALUE="Jan">
<MvASSIGN NAME="g.Month" INDEX="2" MEMBER="name" VALUE="February">
<MvASSIGN NAME="g.Month" INDEX="2" MEMBER="abr" VALUE="Feb">
Month: <MvEVAL EXPR="{ g.Month[g.index]:name }"> <br>
Abbreviation: <MvEVAL EXPR="{ g.Month[g.index]:abr }"> <br>
Whiling Away the Array#
Looping through arrays inside <MvWHILE>
tags—either for assigning values or displaying results—is where they show their true power. This example illustrates several techniques at once.
<MvCOMMENT> Create a dataset </MvCOMMENT>
<MvASSIGN NAME="g.names" VALUE="January,February,March,April,May,June,July,August,September,October,November,December">
<MvASSIGN NAME="g.abbr" VALUE="Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec">
<MvCOMMENT> Convert the data to an array structure. </MvCOMMENT>
<MvASSIGN NAME="g.posn" VALUE="{ 1 }">
<MvWHILE EXPR="{ g.posn LE 12 }">
<MvASSIGN NAME="g.month" INDEX="{ g.posn }" MEMBER="name" VALUE="{ gettoken(g.names, ',', g.posn) }">
<MvASSIGN NAME="g.month" INDEX="{ g.posn }" MEMBER="abbr" VALUE="{ gettoken(g.abbr, ',', g.posn) }">
<MvASSIGN NAME="g.month" INDEX="{ g.posn }" MEMBER="first_date" VALUE="{ g.month[g.posn]:name $ ' 1, ' $ s.tm_year }">
<MvCOMMENT> Next item </MvCOMMENT>
<MvASSIGN NAME="g.posn" VALUE="{ g.posn + 1 }">
</MvWHILE>
Note
The first_date
member contains the formatted date for each month (e.g. January 1, 2010).
<select name="Starting_Month">
<MvASSIGN NAME="g.posn" VALUE="{ 1 }">
<MvWHILE EXPR="{ g.posn LE 12 }">
<option value="{ g.month[g.posn]:abbr }">
<MvEVAL EXPR="{ g.month[g.posn]:first_date }">
</option>
<MvASSIGN NAME="g.posn" VALUE="{ g.posn + 1 }">
</MvWHILE>
</select>
<select name="Starting_Month">
<option value="Jan">January 1, 2010</option>
<option value="Feb">February 1, 2010</option>
<option value="Mar">March 1, 2010</option>
<option value="Apr">April 1, 2010</option>
<option value="May">May 1, 2010</option>
<option value="Jun">June 1, 2010</option>
<option value="Jul">July 1, 2010</option>
<option value="Aug">August 1, 2010</option>
<option value="Sep">September 1, 2010</option>
<option value="Oct">October 1, 2010</option>
<option value="Nov">November 1, 2010</option>
<option value="Dec">December 1, 2010</option>
</select>
Multi Dimensional Arrays#
Multi-dimensional arrays are similar to structures, except elements are referenced by index numbers instead of member names. Only <MvDIMENSION>
and <MvMEMBER>
tags are allowed inside an <MvASSIGNARRAY>
block.
<MvASSIGN NAME="g.page" VALUE="{ 2 }">
<MvASSIGN NAME="g.row" VALUE="{ 1 }">
<MvASSIGN NAME="g.column" VALUE="{ 1 }">
<MvASSIGNARRAY NAME="g.dataset" VALUE="{ g.data_value }">
<MvDIMENSION INDEX="{ g.page }">
<MvDIMENSION INDEX="{ g.row }">
<MvDIMENSION INDEX="{ g.column }">
</MvASSIGNARRAY>
Multi Dimensional Array Structures#
Multi-dimensional arrays can also contain structures (members), allowing you to create nested array structures.
<MvASSIGNARRAY NAME="l.attributes" VALUE="{ l.price }">
<MvDIMENSION INDEX="{ l.product_attribute_count }">
<MvMEMBER NAME="options">
<MvDIMENSION INDEX="{ l.opt_posn }">
<MvMEMBER NAME="price">
</MvASSIGNARRAY>
<MvASSIGNARRAY NAME="l.attributes" VALUE="{ l.cost }">
<MvDIMENSION INDEX="{ l.product_attribute_count }">
<MvMEMBER NAME="options">
<MvDIMENSION INDEX="{ l.opt_posn }">
<MvMEMBER NAME="cost">
</MvASSIGNARRAY>
Option Price: <MvEVAL EXPR="{ l.attributes[1]:options[1]price }"> <br>
Option Cost: <MvEVAL EXPR="{ l.attributes[1]:options[1]cost }"> <br>
Simplify your code using MvREFERENCE
#
The attributes array above could be part of an even larger multi-array data structure. Using <MvASSIGNARRAY>
to add each options[n]:member
value can become unwieldy. Instead, use <MvREFERENCE>
to create a reference from one variable to another, so changes to one affect the other. This is more readable and easier to debug.
<MvREFERENCE NAME="l.option"
VARIABLE="{ 'l.products[' $ l.prod_index $
']:attributes[' $ l.attr_index $
']:options[' $ l.opt_index $ ']' }">
<MvASSIGN NAME="l.option:code" VALUE="{ g.code }">
<MvASSIGN NAME="l.option:prompt" VALUE="{ g.prompt }">
<MvASSIGN NAME="l.option:price" VALUE="{ g.price }">
<MvASSIGN NAME="l.option:cost" VALUE="{ g.cost }">
Note
The expression in the VARIABLE
attribute creates a string representation of a particular array element (e.g. l.products[1]:attributes[1]:options[1]
).