Skip to content

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.

Load the Array
<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).

Output the Array
<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>
Results
<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]).