|
Arrays & StructuresArrays 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 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 usually used, for complex multi dimensional arrays or structures, the latter can often makes the the script more readable. The final example illustrates using <MvREFERENCE> combined with <MvASSIGN>. Many experience Miva Script programmers prefer this method for complex array structures. When passing arrays as parameters in a user defined function <MvFUNCTION>, it is more efficient to declare the parameter with the VAR keyword, passing the array by reference rather than passing a copy of the array. This also allow you to directly alter the array within the function rather than altering the copy and returning the copy with <MvFUNCTIONRETURN>. Simple StructuresThis examples show a simple structured variable where each MEMBER is an attribute of the variable. Simple Assignement:<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 ArraysThis examples show arrays with the index first as a literal number, than as a variable. It also creates two arrays to contain different but related data. These can be combined into a single more efficient structure. In practice, arrays are nearly always used with a <MvWHILE> loop so that a few lines of code, can quickly generated hundreds or thousands of assignments. Miva Script provides a two ways to create arrays and flexibility in the ways to access or manipulate their values. The examples below increase in power and complexity. Simple Assignement:<MvASSIGN NAME = "g.Month_Name" INDEX = "1" VALUE = "January" > <MvASSIGN NAME = "g.Month_Name" INDEX = "2" VALUE = "Feburary" > <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 StructuresArray structures can be used to represent more complex data. This example joins the two arrays above into a single structure stored in the variable g.Month. Compare this to a spreadsheet or database where each index is a row and each member is named column. Arrays with Members:<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 = "Feburary" > <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 ArrayLooping through arrays inside <MvWHILE> tags, either for assigning values or displaying results, is where they show their true power. This example illustrates several important techniques at once. Study it carefully. The variables g.names and g.abbr contain lists of literal data. Frequently we deal with data from a database or external files that we want to read into an array or structure. NOTE: Loops are not limited to positive increments. You can display your array in reverse order if desired. 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) Once loaded, loop through the array again to display it. In this example we populate an HTML <select> dropdown. box. 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: Multi Dimensional ArraysMulti dimension arrays are similar to structures except elements are referenced by index numbers instead of member names. Only <MvDIMENSION> and <MvMEMBER> tags are allowed inside a <MvASSIGNARRAY> block. Example:<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 StructuresMulti dimension arrays can also contain structures (members) allowing you to create nested array structures. Example:<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 MvREFERENCEThe attributes array above could be a subset of an even larger multi array data structure like this 3 dimensional array structure. Complex data set:l.products[l.prod_index]:code l.products[l.prod_index]:name l.products[l.prod_index]:descrip l.products[l.prod_index]:attributes[l.attr_index]:code l.products[l.prod_index]:attributes[l.attr_index]:prompt l.products[l.prod_index]:attributes[l.attr_index]:options[l.opt_index]:code l.products[l.prod_index]:attributes[l.attr_index]:options[l.opt_index]:prompt l.products[l.prod_index]:attributes[l.attr_index]:options[l.opt_index]:price l.products[l.prod_index]:attributes[l.attr_index]:options[l.opt_index]:cost Obviously with the addition of a few members at each level this could be a very large array. Using MvASSIGNARRAY to add each options[n]:member value could end up with a very long list of complex tags. In this example the variable l.option is referenced to a single array record in the much larger l.products array. the tag <MvREFERENCE> creates a reference from one variable to another, such that changes to one will be made to the other. Not only is this more readable it's far easier to debug. Example:<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. the first array element would be l.products[1]:attributes[1]:options[1] ). |