Announcement

Collapse
No announcement yet.

Dynamic Arrays and miva_variable_value()

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Dynamic Arrays and miva_variable_value()



    MivaScript's array handling seems to be pretty strangely implemented or else
    I'm just dumb. I can't figure out how to do this with the
    miva_variable_value() function or macro's. Neither seem to work with
    structured arrays.

    I have a situation where I can't know how many dimensions my array will
    require beforehand. I'm loading the entire category tree into a structure
    and since there is no way to re-dimension an array and retain it's values
    I've been coding using the old techniques formerly supported using macro's.

    I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
    g.cattree_1_1_n:code.
    Top level category: g.cattree_1:id,
    Parent level category: g.cattree_1_1:id
    Child level category: g.cattree_1_1_1:id and so on for as many levels as
    needed.

    Where l.cat_var is a string in the form "1_1", I have successfully stored
    data in this pseudo array using this technique.
    <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
    <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">

    BUT, I can't get the data back out.
    Again, where l.cat_var is t string "1_1" the assignment below produces the
    string "g.catree_1_1:id"
    <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
    ':id' }">

    This assignment fails to do anything...
    <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)
    }">

    However, this assignment works!
    <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">

    Question:
    Once I have created this string "g.catree_1_1:id" as the name if a variable
    that holds Categories.d.id, how do I use that string to get the id stored in
    a simple variable?

    Comment:
    I've already tried <MvEVAL EXPR="{&[l.cat_string];}"> exactly like the
    documentation shows.
    The compiler produces this error. Found unexpected "&" in expression

    Ray Yates



    I eventually figured out


    Ray Yates
    <A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>



    #2
    Dynamic Arrays and miva_variable_value()



    Did you get it working?

    The code below basically does what you are looking for from what I could
    glean from your emails.

    <MvCOMMENT>Set l.cat_var to: 1_1</MvCOMMENT>
    <MvASSIGN NAME = "l.cat_var" VALUE = "{ '1_1' }">

    <MvCOMMENT>asssign 12345 to "g.cattree_1_1:id"</MvCOMMENT>
    <MvASSIGN NAME = "{ 'g.cattree_' $ l.cat_var $ ':id' }" VALUE = "{
    '12345' }">

    <MvCOMMENT>Create your category variable string</MvCOMMENT>
    <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $ ':id' }">

    <MvEVAL EXPR = "{'l.cat_string: ' $ l.cat_string $ '
    '}">

    <MvCOMMENT>Assign l.cat_id the value of l.cat_string (12345)</MvCOMMENT>
    <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)}">

    <MvCOMMENT>Evaluate the data</MvCOMMENT>
    <MvEVAL EXPR = "{'Data: ' $ l.cat_id}">

    Scot
    <A HREF ="http://www.scotsscripts.com">http://www.scotsscripts.com</A>

    Ray Yates wrote:
    > MivaScript's array handling seems to be pretty strangely implemented or else
    > I'm just dumb. I can't figure out how to do this with the
    > miva_variable_value() function or macro's. Neither seem to work with
    > structured arrays.
    >
    > I have a situation where I can't know how many dimensions my array will
    > require beforehand. I'm loading the entire category tree into a structure
    > and since there is no way to re-dimension an array and retain it's values
    > I've been coding using the old techniques formerly supported using macro's.
    >
    > I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
    > g.cattree_1_1_n:code.
    > Top level category: g.cattree_1:id,
    > Parent level category: g.cattree_1_1:id
    > Child level category: g.cattree_1_1_1:id and so on for as many levels as
    > needed.
    >
    > Where l.cat_var is a string in the form "1_1", I have successfully stored
    > data in this pseudo array using this technique.
    > <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
    > <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">
    >
    > BUT, I can't get the data back out.
    > Again, where l.cat_var is t string "1_1" the assignment below produces the
    > string "g.catree_1_1:id"
    > <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
    > ':id' }">
    >
    > This assignment fails to do anything...
    > <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)
    > }">
    >
    > However, this assignment works!
    > <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">
    >
    > Question:
    > Once I have created this string "g.catree_1_1:id" as the name if a variable
    > that holds Categories.d.id, how do I use that string to get the id stored in
    > a simple variable?
    >
    > Comment:
    > I've already tried <MvEVAL EXPR="{&[l.cat_string];}"> exactly like the
    > documentation shows.
    > The compiler produces this error. Found unexpected "&" in expression
    >
    > Ray Yates
    >
    >
    >
    > I eventually figured out
    >
    >
    > Ray Yates
    > <A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>
    >
    >

    Comment


      #3
      Re: Dynamic Arrays and miva_variable_value()



      I got it solved. Thanks to everyone that posted.

      There seems to be a problem (at least on my site) with the handling of structures by miva_variable_value(). I finally realized (duh) that since I'm using a Pseudo Array anyway I could just use a Pseudo Structure as well.

      <mvassign name="l.cat_var" value="1_1">
      <mvassign name="g.cattreeid_1_1" value="204">
      <MvASSIGN NAME="l.cat" VALUE="{ miva_variable_value('g.cattreeid_' $ l.cat_var) }">
      <MvEVAL EXPR="{l.cat}">

      My "array" will contain similarly named g.cattreename_ and g.cattreecode elements.

      Let me explain l.cat_var" value="1_1

      Since I can't know how deep the tree is g.cattreeid_1, g.cattreeid_2, g.cattreeid_3 and so on contain the top level category id's. g.cattreeid_1_1, _1_2, _1_3 and so on is the branch below the first top level category. g.cattreeid_4_4_3_1 would be a branch 4 levels deep starting at the 4th top category, 4th parent category, 3rd child category, 1st grandchild etc. As I build the array, I keep track of the depth of each level in a stack array and call a recursive routine to populate all the branches. a Multi dimensional array would have been way more convient to code (as I did on the first crack at this) but Mivascript arrays can't be re-sized and retain their values. So you would have to "pick" an arbitrary depth up front and/or pass a fixed depth to the function.



      Scot Ranney [email protected] Wrote:
      >
      >Did you get it working?
      >
      >The code below basically does what you are looking for from what I could
      >glean from your emails.
      >
      ><MvCOMMENT>Set l.cat_var to: 1_1</MvCOMMENT>
      ><MvASSIGN NAME = "l.cat_var" VALUE = "{ '1_1' }">
      >
      ><MvCOMMENT>asssign 12345 to "g.cattree_1_1:id"</MvCOMMENT>
      ><MvASSIGN NAME = "{ 'g.cattree_' $ l.cat_var $ ':id' }" VALUE = "{
      >'12345' }">
      >
      ><MvCOMMENT>Create your category variable string</MvCOMMENT>
      ><MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $ ':id' }">
      >
      ><MvEVAL EXPR = "{'l.cat_string: ' $ l.cat_string $ '
      '}">
      >
      ><MvCOMMENT>Assign l.cat_id the value of l.cat_string (12345)</MvCOMMENT>
      ><MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)}">
      >
      ><MvCOMMENT>Evaluate the data</MvCOMMENT>
      ><MvEVAL EXPR = "{'Data: ' $ l.cat_id}">
      >
      >Scot
      ><A HREF ="http://www.scotsscripts.com">http://www.scotsscripts.com</A>
      >
      >Ray Yates wrote:
      >> MivaScript's array handling seems to be pretty strangely implemented or else
      >> I'm just dumb. I can't figure out how to do this with the
      >> miva_variable_value() function or macro's. Neither seem to work with
      >> structured arrays.
      >>
      >> I have a situation where I can't know how many dimensions my array will
      >> require beforehand. I'm loading the entire category tree into a structure
      >> and since there is no way to re-dimension an array and retain it's values
      >> I've been coding using the old techniques formerly supported using macro's.
      >>
      >> I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
      >> g.cattree_1_1_n:code.
      >> Top level category: g.cattree_1:id,
      >> Parent level category: g.cattree_1_1:id
      >> Child level category: g.cattree_1_1_1:id and so on for as many levels as
      >> needed.
      >>
      >> Where l.cat_var is a string in the form "1_1", I have successfully stored
      >> data in this pseudo array using this technique.
      >> <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
      >> <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">
      >>
      >> BUT, I can't get the data back out.
      >> Again, where l.cat_var is t string "1_1" the assignment below produces the
      >> string "g.catree_1_1:id"
      >> <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
      >> ':id' }">
      >>
      >> This assignment fails to do anything...
      >> <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)
      >> }">
      >>
      >> However, this assignment works!
      >> <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">
      >>
      >> Question:
      >> Once I have created this string "g.catree_1_1:id" as the name if a variable
      >> that holds Categories.d.id, how do I use that string to get the id stored in
      >> a simple variable?
      >>
      >> Comment:
      >> I've already tried <MvEVAL EXPR="{[l.cat_string]}"> exactly like the
      >> documentation shows.
      >> The compiler produces this error. Found unexpected "" in expression
      >>
      >> Ray Yates
      >>
      >>
      >>
      >> I eventually figured out
      >>
      >>
      >> Ray Yates
      >> <A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>
      >>
      >>
      >
      --
      From: Ray Yates <[email protected]>

      Comment


        #4
        Re: Dynamic Arrays and miva_variable_value()



        Hi Ray,

        " a Multi dimensional array would have been way more convient to code (as I
        did on the first crack at this) but Mivascript arrays can't be re-sized and
        retain their values. So you would have to "pick" an arbitrary depth up front
        and/or pass a fixed depth to the function."

        There are several ways to resize arrays and keeping their values. Also using
        MD-arrays/structures is definitely easier and faster. In any event you might
        need to run two full loops through your category array.

        Imagine you have a table with an ID, PARENT and label, where PARENT refers
        to ID.

        First create two arrays/structures with all records.

        <MvWHILE EXPR = "{ NOT d.eof }">

        <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values)+1 }"
        MEMBER="ID" VALUE = "{ d.id }" >
        <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values) }"
        MEMBER="LABEL" VALUE = "{ d.label }" >

        <MvIF EXPR = "{ NOT d.parent }" >
        // if the record is the top level and has no parent
        <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
        miva_array_max(g.values) }" >
        <MvMEMBER NAME="ROOT">
        <MvDIMENSION INDEX="{
        miva_array_max(miva_variable_value('g.assignment:' $d.parent)+1 }">
        </MvASSIGNARRAY>
        <MvELSE>
        <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
        miva_array_max(g.values) }" >
        <MvMEMBER NAME="{d.parent}">
        <MvDIMENSION INDEX="{
        miva_array_max(miva_variable_value('g.assignment:' $d.parent)+1 }">
        </MvASSIGNARRAY>
        </MvIF>
        <MvSKIP>
        </MvWHILE>

        // Start a recursive functioncall, beginning with the
        g.assignement:ROOT-level

        <MvEVAL EXPR = "{ display_branches('root') }" >

        This is then the function that displays the tree.

        <MvFUNCTION NAME = "display_branches" PARAMETERS="parent_id"
        STANDARDOUTPUTLEVEL = "html,text,compresswhitespace">
        //get the count of the members on this level
        <MvASSIGN NAME = "l.max" VALUE = "{ miva_array_max(
        miva_variable_value('g.assignment:'$l.parent_id) }" >

        <ul>
        <MvASSIGN NAME = "l.a" VALUE = "1" >
        <MvWHILE EXPR = "{ l.a LE l.max }">

        // Get the current ID, for clarity reason here.
        <MvASSIGN NAME = "l.id" VALUE = "{
        miva_variable_value('g.assignment:'$l.parent_id$'['$l.a$']') }" >

        [*]<MvEVAL EXPR = "{ g.values[l.id]:ID }" >....<MvEVAL EXPR
        = "{ g.values[l.id]:LABEL }" >

        <MvIF EXPR = "{ miva_variable_value(
        'g.assignment:'$l.id$'[1]') }">
        // if a child exist calls the same function again , but this
        time (instead of using 'root' as the parameter, it uses the ID.

        <MvEVAL EXPR = "{ display_branches(miva_variable_value(
        'g.assignment:'$g.values[l.id]:ID$'[1]') ) }" >
        </MvIF>

        <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" >
        </MvWHILE>
        [/list]
        </MvFUNCTION>



        This is written blindly and NOT TESTED, but I have used this technique
        numerous times and it works quite well. It is however very important to add
        some security measures into it, to a.) prevent infinitive recursive
        functioncalls and b.) to avoid non-integer values for l.id (in the
        array-indices of g.values[l.id]:ID in display_branches()).

        The nice thing this technique allows with a little modification to add
        complex sorting of your trees, independently of a database index, and or
        expanded or collapsed branches.


        ...
        You should also look into the functions miva_array_deserialize() and
        miva_array_collapse(). Both can be very helpful.

        For example, instead of using my "miva_array_max(g.values)+1" , you could
        write a simple, comma separated string, and then at the end deserialize it,
        which then returns a real array. You just have to make sure that certain
        characters are not in the string, like '=',':' etc.

        So a list like miva_array_deserialize('abc,def,aaa,cde') gives you the array
        [1]=abc,[2]=def,[3]=aaa,[4]=cde



        Hope that helps,

        Markus










        -----Original Message-----
        From: [email protected] [mailto:[email protected]] On Behalf
        Of [email protected]
        Sent: Friday, January 28, 2005 4:41 PM
        To: [email protected]
        Cc: [email protected]
        Subject: [meu] Re: Dynamic Arrays and miva_variable_value()

        I got it solved. Thanks to everyone that posted.

        There seems to be a problem (at least on my site) with the handling of
        structures by miva_variable_value(). I finally realized (duh) that since I'm
        using a Pseudo Array anyway I could just use a Pseudo Structure as well.

        <mvassign name="l.cat_var" value="1_1">
        <mvassign name="g.cattreeid_1_1" value="204">
        <MvASSIGN NAME="l.cat" VALUE="{ miva_variable_value('g.cattreeid_' $
        l.cat_var) }">
        <MvEVAL EXPR="{l.cat}">

        My "array" will contain similarly named g.cattreename_ and g.cattreecode
        elements.

        Let me explain l.cat_var" value="1_1

        Since I can't know how deep the tree is g.cattreeid_1, g.cattreeid_2,
        g.cattreeid_3 and so on contain the top level category id's.
        g.cattreeid_1_1, _1_2, _1_3 and so on is the branch below the first top
        level category. g.cattreeid_4_4_3_1 would be a branch 4 levels deep starting
        at the 4th top category, 4th parent category, 3rd child category, 1st
        grandchild etc. As I build the array, I keep track of the depth of each
        level in a stack array and call a recursive routine to populate all the
        branches. a Multi dimensional array would have been way more convient to
        code (as I did on the first crack at this) but Mivascript arrays can't be
        re-sized and retain their values. So you would have to "pick" an arbitrary
        depth up front and/or pass a fixed depth to the function.



        Scot Ranney [email protected] Wrote:
        >
        >Did you get it working?
        >
        >The code below basically does what you are looking for from what I
        >could glean from your emails.
        >
        ><MvCOMMENT>Set l.cat_var to: 1_1</MvCOMMENT> <MvASSIGN NAME =
        >"l.cat_var" VALUE = "{ '1_1' }">
        >
        ><MvCOMMENT>asssign 12345 to "g.cattree_1_1:id"</MvCOMMENT> <MvASSIGN
        >NAME = "{ 'g.cattree_' $ l.cat_var $ ':id' }" VALUE = "{ '12345' }">
        >
        ><MvCOMMENT>Create your category variable string</MvCOMMENT> <MvASSIGN
        >NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $ ':id' }">
        >
        ><MvEVAL EXPR = "{'l.cat_string: ' $ l.cat_string $ '
        '}">
        >
        ><MvCOMMENT>Assign l.cat_id the value of l.cat_string
        >(12345)</MvCOMMENT> <MvASSIGN NAME="l.cat_id" VALUE="{
        >miva_variable_value(l.cat_string)}">
        >
        ><MvCOMMENT>Evaluate the data</MvCOMMENT> <MvEVAL EXPR = "{'Data: ' $
        >l.cat_id}">
        >
        >Scot
        ><A HREF ="http://www.scotsscripts.com">http://www.scotsscripts.com</A>
        >
        >Ray Yates wrote:
        >> MivaScript's array handling seems to be pretty strangely implemented
        >> or else I'm just dumb. I can't figure out how to do this with the
        >> miva_variable_value() function or macro's. Neither seem to work with
        >> structured arrays.
        >>
        >> I have a situation where I can't know how many dimensions my array
        >> will require beforehand. I'm loading the entire category tree into a
        >> structure and since there is no way to re-dimension an array and
        >> retain it's values I've been coding using the old techniques formerly
        supported using macro's.
        >>
        >> I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
        >> g.cattree_1_1_n:code.
        >> Top level category: g.cattree_1:id,
        >> Parent level category: g.cattree_1_1:id Child level category:
        >> g.cattree_1_1_1:id and so on for as many levels as needed.
        >>
        >> Where l.cat_var is a string in the form "1_1", I have successfully
        >> stored data in this pseudo array using this technique.
        >> <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
        >> <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">
        >>
        >> BUT, I can't get the data back out.
        >> Again, where l.cat_var is t string "1_1" the assignment below
        >> produces the string "g.catree_1_1:id"
        >> <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
        >> ':id' }">
        >>
        >> This assignment fails to do anything...
        >> <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)

        >> }">
        >>
        >> However, this assignment works!
        >> <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">
        >>
        >> Question:
        >> Once I have created this string "g.catree_1_1:id" as the name if a
        >> variable that holds Categories.d.id, how do I use that string to get
        >> the id stored in a simple variable?
        >>
        >> Comment:
        >> I've already tried <MvEVAL EXPR="{[l.cat_string]}"> exactly like the
        >> documentation shows.
        >> The compiler produces this error. Found unexpected "" in expression
        >>
        >> Ray Yates
        >>
        >>
        >>
        >> I eventually figured out
        >>
        >>
        >> Ray Yates
        >> <A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>
        >>
        >>
        >
        --
        From: Ray Yates <[email protected]>

        Comment


          #5
          Re: Dynamic Arrays and miva_variable_value()



          Howdy Markus,

          I'm jumping into these arrays... look like they should be slick, but
          i'm having a hard time making miva_variable_value() work inside
          miva_array_max().

          I've been working with the sameple code you posted and this:
          <MvASSIGN NAME = "l.max" VALUE = "{
          miva_array_max(miva_variable_value('g.assignment:' $l.parent_id))}" >

          gets me this...

          Expression Error: Parameter 'aggregate' in call to function
          'miva_array_max' expects a variable, found an expression or constant

          Does this only work in compiled scripts?

          Cheers,

          jim



          At 6:34 PM -0500 1/28/05, MvMarkus wrote:
          >Hi Ray,
          >
          >" a Multi dimensional array would have been way more convient to code (as I
          >did on the first crack at this) but Mivascript arrays can't be re-sized and
          >retain their values. So you would have to "pick" an arbitrary depth up front
          >and/or pass a fixed depth to the function."
          >
          >There are several ways to resize arrays and keeping their values. Also using
          >MD-arrays/structures is definitely easier and faster. In any event you might
          >need to run two full loops through your category array.
          >
          >Imagine you have a table with an ID, PARENT and label, where PARENT refers
          >to ID.
          >
          >First create two arrays/structures with all records.
          >
          > <MvWHILE EXPR = "{ NOT d.eof }">
          >
          > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values)+1 }"
          >MEMBER="ID" VALUE = "{ d.id }" >
          > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values) }"
          >MEMBER="LABEL" VALUE = "{ d.label }" >
          >
          > <MvIF EXPR = "{ NOT d.parent }" >
          > // if the record is the top level and has no parent
          > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
          >miva_array_max(g.values) }" >
          > <MvMEMBER NAME="ROOT">
          > <MvDIMENSION INDEX="{
          >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
          > </MvASSIGNARRAY>
          > <MvELSE>
          > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
          >miva_array_max(g.values) }" >
          > <MvMEMBER NAME="{d.parent}">
          > <MvDIMENSION INDEX="{
          >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
          > </MvASSIGNARRAY>
          > </MvIF>
          > <MvSKIP>
          ></MvWHILE>
          >
          > // Start a recursive functioncall, beginning with the
          >g.assignement:ROOT-level
          >
          ><MvEVAL EXPR = "{ display_branches('root') }" >
          >
          >This is then the function that displays the tree.
          >
          ><MvFUNCTION NAME = "display_branches" PARAMETERS="parent_id"
          >STANDARDOUTPUTLEVEL = "html,text,compresswhitespace">
          > //get the count of the members on this level
          > <MvASSIGN NAME = "l.max" VALUE = "{ miva_array_max(
          >miva_variable_value('g.assignment:'$l.parent_id ) }" >
          >
          > <ul>
          > <MvASSIGN NAME = "l.a" VALUE = "1" >
          > <MvWHILE EXPR = "{ l.a LE l.max }">
          >
          > // Get the current ID, for clarity reason here.
          > <MvASSIGN NAME = "l.id" VALUE = "{
          >miva_variable_value('g.assignment:'$l.parent_id $'['$l.a$']') }" >
          >
          > [*]<MvEVAL EXPR = "{ g.values[l.id]:ID }" >....<MvEVAL EXPR
          >= "{ g.values[l.id]:LABEL }" >
          >
          > <MvIF EXPR = "{ miva_variable_value(
          >'g.assignment:'$l.id$'[1]') }">
          > // if a child exist calls the same function again , but this
          >time (instead of using 'root' as the parameter, it uses the ID.
          >
          > <MvEVAL EXPR = "{ display_branches(miva_variable_value(
          >'g.assignment:'$g.values[l.id]:ID$'[1]') ) }" >
          > </MvIF>
          >
          > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" >
          > </MvWHILE>
          > [/list]
          ></MvFUNCTION>
          >
          >
          >
          >This is written blindly and NOT TESTED, but I have used this technique
          >numerous times and it works quite well. It is however very important to add
          >some security measures into it, to a.) prevent infinitive recursive
          >functioncalls and b.) to avoid non-integer values for l.id (in the
          >array-indices of g.values[l.id]:ID in display_branches()).
          >
          >The nice thing this technique allows with a little modification to add
          >complex sorting of your trees, independently of a database index, and or
          >expanded or collapsed branches.
          >
          >
          >...
          >You should also look into the functions miva_array_deserialize() and
          >miva_array_collapse(). Both can be very helpful.
          >
          >For example, instead of using my "miva_array_max(g.values)+1" , you could
          >write a simple, comma separated string, and then at the end deserialize it,
          >which then returns a real array. You just have to make sure that certain
          >characters are not in the string, like '=',':' etc.
          >
          >So a list like miva_array_deserialize('abc,def,aaa,cde') gives you the array
          >[1]=abc,[2]=def,[3]=aaa,[4]=cde
          >
          >
          >
          >Hope that helps,
          >
          >Markus
          >
          >
          >
          >
          >
          >
          >
          >
          >
          >
          >-----Original Message-----
          >From: [email protected] [mailto:[email protected]] On Behalf
          >Of [email protected]
          >Sent: Friday, January 28, 2005 4:41 PM
          >To: [email protected]
          >Cc: [email protected]
          >Subject: [meu] Re: Dynamic Arrays and miva_variable_value()
          >
          >I got it solved. Thanks to everyone that posted.
          >
          >There seems to be a problem (at least on my site) with the handling of
          >structures by miva_variable_value(). I finally realized (duh) that since I'm
          >using a Pseudo Array anyway I could just use a Pseudo Structure as well.
          >
          ><mvassign name="l.cat_var" value="1_1">
          ><mvassign name="g.cattreeid_1_1" value="204">
          > <MvASSIGN NAME="l.cat" VALUE="{ miva_variable_value('g.cattreeid_' $
          >l.cat_var) }">
          > <MvEVAL EXPR="{l.cat}">
          >
          >My "array" will contain similarly named g.cattreename_ and g.cattreecode
          >elements.
          >
          >Let me explain l.cat_var" value="1_1
          >
          >Since I can't know how deep the tree is g.cattreeid_1, g.cattreeid_2,
          >g.cattreeid_3 and so on contain the top level category id's.
          >g.cattreeid_1_1, _1_2, _1_3 and so on is the branch below the first top
          >level category. g.cattreeid_4_4_3_1 would be a branch 4 levels deep starting
          >at the 4th top category, 4th parent category, 3rd child category, 1st
          >grandchild etc. As I build the array, I keep track of the depth of each
          >level in a stack array and call a recursive routine to populate all the
          >branches. a Multi dimensional array would have been way more convient to
          >code (as I did on the first crack at this) but Mivascript arrays can't be
          >re-sized and retain their values. So you would have to "pick" an arbitrary
          >depth up front and/or pass a fixed depth to the function.
          >
          >
          >
          >Scot Ranney [email protected] Wrote:
          >>
          >>Did you get it working?
          >>
          >>The code below basically does what you are looking for from what I
          >>could glean from your emails.
          >>
          >><MvCOMMENT>Set l.cat_var to: 1_1</MvCOMMENT> <MvASSIGN NAME =
          >>"l.cat_var" VALUE = "{ '1_1' }">
          >>
          >><MvCOMMENT>asssign 12345 to "g.cattree_1_1:id"</MvCOMMENT> <MvASSIGN
          >>NAME = "{ 'g.cattree_' $ l.cat_var $ ':id' }" VALUE = "{ '12345' }">
          >>
          >><MvCOMMENT>Create your category variable string</MvCOMMENT> <MvASSIGN
          >>NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $ ':id' }">
          >>
          >><MvEVAL EXPR = "{'l.cat_string: ' $ l.cat_string $ '
          '}">
          >>
          >><MvCOMMENT>Assign l.cat_id the value of l.cat_string
          >>(12345)</MvCOMMENT> <MvASSIGN NAME="l.cat_id" VALUE="{
          >>miva_variable_value(l.cat_string)}">
          >>
          >><MvCOMMENT>Evaluate the data</MvCOMMENT> <MvEVAL EXPR = "{'Data: ' $
          >>l.cat_id}">
          >>
          >>Scot
          >><A HREF ="http://www.scotsscripts.com">http://www.scotsscripts.com</A>
          >>
          >>Ray Yates wrote:
          >>> MivaScript's array handling seems to be pretty strangely implemented
          >>> or else I'm just dumb. I can't figure out how to do this with the
          >>> miva_variable_value() function or macro's. Neither seem to work with
          >>> structured arrays.
          >>>
          >>> I have a situation where I can't know how many dimensions my array
          >>> will require beforehand. I'm loading the entire category tree into a
          >>> structure and since there is no way to re-dimension an array and
          >>> retain it's values I've been coding using the old techniques formerly
          >supported using macro's.
          >>>
          >>> I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
          >>> g.cattree_1_1_n:code.
          >>> Top level category: g.cattree_1:id,
          >>> Parent level category: g.cattree_1_1:id Child level category:
          >>> g.cattree_1_1_1:id and so on for as many levels as needed.
          >>>
          >>> Where l.cat_var is a string in the form "1_1", I have successfully
          >>> stored data in this pseudo array using this technique.
          >>> <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
          >>> <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">
          > >>
          >>> BUT, I can't get the data back out.
          >>> Again, where l.cat_var is t string "1_1" the assignment below
          >>> produces the string "g.catree_1_1:id"
          >>> <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
          >>> ':id' }">
          >>>
          >>> This assignment fails to do anything...
          >>> <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)
          >
          >>> }">
          >>>
          >>> However, this assignment works!
          >>> <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">
          >>>
          >>> Question:
          >>> Once I have created this string "g.catree_1_1:id" as the name if a
          >>> variable that holds Categories.d.id, how do I use that string to get
          >>> the id stored in a simple variable?
          >>>
          >>> Comment:
          >>> I've already tried <MvEVAL EXPR="{[l.cat_string]}"> exactly like the
          >>> documentation shows.
          >>> The compiler produces this error. Found unexpected "" in expression
          >>>
          >>> Ray Yates
          >>>
          >>>
          >>>
          >>> I eventually figured out
          >>>
          >>>
          >>> Ray Yates
          >>> <A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>
          >>>
          >>>
          >>
          >--
          >From: Ray Yates <[email protected]>
          >

          Comment


            #6
            Re: Dynamic Arrays and miva_variable_value()



            Hi Jim,

            Normally that should work, but you can of course always try this by breaking
            it into two lines:

            <MvASSIGN NAME = "l.array" VALUE =
            "{miva_variable_value('g.assignment:'$l.parent_id) }" >
            <MvASSIGN NAME = "l.max" VALUE = "{miva_variable_max(l.array)}" >

            See if this works. I'm using the compiler for too long by now, so I don't
            really recall what works and what doesn't when its not compiled.


            Markus


            -----Original Message-----
            From: [email protected] [mailto:[email protected]] On Behalf
            Of jim cranford
            Sent: Saturday, January 29, 2005 7:07 PM
            To: MvMarkus; [email protected]; [email protected]
            Cc: [email protected]
            Subject: RE: [meu] Re: Dynamic Arrays and miva_variable_value()

            Howdy Markus,

            I'm jumping into these arrays... look like they should be slick, but i'm
            having a hard time making miva_variable_value() work inside
            miva_array_max().

            I've been working with the sameple code you posted and this:
            <MvASSIGN NAME = "l.max" VALUE = "{
            miva_array_max(miva_variable_value('g.assignment:' $l.parent_id))}" >

            gets me this...

            Expression Error: Parameter 'aggregate' in call to function 'miva_array_max'
            expects a variable, found an expression or constant

            Does this only work in compiled scripts?

            Cheers,

            jim



            At 6:34 PM -0500 1/28/05, MvMarkus wrote:
            >Hi Ray,
            >
            >" a Multi dimensional array would have been way more convient to code
            >(as I did on the first crack at this) but Mivascript arrays can't be
            >re-sized and retain their values. So you would have to "pick" an
            >arbitrary depth up front and/or pass a fixed depth to the function."
            >
            >There are several ways to resize arrays and keeping their values. Also
            >using MD-arrays/structures is definitely easier and faster. In any
            >event you might need to run two full loops through your category array.
            >
            >Imagine you have a table with an ID, PARENT and label, where PARENT
            >refers to ID.
            >
            >First create two arrays/structures with all records.
            >
            > <MvWHILE EXPR = "{ NOT d.eof }">
            >
            > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values)+1 }"
            >MEMBER="ID" VALUE = "{ d.id }" >
            > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values) }"
            >MEMBER="LABEL" VALUE = "{ d.label }" >
            >
            > <MvIF EXPR = "{ NOT d.parent }" >
            > // if the record is the top level and has no parent
            > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
            >miva_array_max(g.values) }" >
            > <MvMEMBER NAME="ROOT">
            > <MvDIMENSION INDEX="{
            >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
            > </MvASSIGNARRAY>
            > <MvELSE>
            > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
            >miva_array_max(g.values) }" >
            > <MvMEMBER NAME="{d.parent}">
            > <MvDIMENSION INDEX="{
            >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
            > </MvASSIGNARRAY>
            > </MvIF>
            > <MvSKIP>
            ></MvWHILE>
            >
            > // Start a recursive functioncall, beginning with the
            >g.assignement:ROOT-level
            >
            ><MvEVAL EXPR = "{ display_branches('root') }" >
            >
            >This is then the function that displays the tree.
            >
            ><MvFUNCTION NAME = "display_branches" PARAMETERS="parent_id"
            >STANDARDOUTPUTLEVEL = "html,text,compresswhitespace">
            > //get the count of the members on this level
            > <MvASSIGN NAME = "l.max" VALUE = "{ miva_array_max(
            >miva_variable_value('g.assignment:'$l.parent_id ) }" >
            >
            > <ul>
            > <MvASSIGN NAME = "l.a" VALUE = "1" >
            > <MvWHILE EXPR = "{ l.a LE l.max }">
            >
            > // Get the current ID, for clarity reason here.
            > <MvASSIGN NAME = "l.id" VALUE = "{
            >miva_variable_value('g.assignment:'$l.parent_id $'['$l.a$']') }" >
            >
            > [*]<MvEVAL EXPR = "{ g.values[l.id]:ID }" >....<MvEVAL EXPR
            = "{
            >g.values[l.id]:LABEL }" >
            >
            > <MvIF EXPR = "{ miva_variable_value(
            >'g.assignment:'$l.id$'[1]') }">
            > // if a child exist calls the same function again , but this
            time
            >(instead of using 'root' as the parameter, it uses the ID.
            >
            > <MvEVAL EXPR = "{ display_branches(miva_variable_value(
            >'g.assignment:'$g.values[l.id]:ID$'[1]') ) }" >
            > </MvIF>
            >
            > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" >
            > </MvWHILE>
            > [/list]
            ></MvFUNCTION>
            >
            >
            >
            >This is written blindly and NOT TESTED, but I have used this technique
            >numerous times and it works quite well. It is however very important to
            >add some security measures into it, to a.) prevent infinitive recursive
            >functioncalls and b.) to avoid non-integer values for l.id (in the
            >array-indices of g.values[l.id]:ID in display_branches()).
            >
            >The nice thing this technique allows with a little modification to add
            >complex sorting of your trees, independently of a database index, and
            >or expanded or collapsed branches.
            >
            >
            >...
            >You should also look into the functions miva_array_deserialize() and
            >miva_array_collapse(). Both can be very helpful.
            >
            >For example, instead of using my "miva_array_max(g.values)+1" , you
            >could write a simple, comma separated string, and then at the end
            >deserialize it, which then returns a real array. You just have to make
            >sure that certain characters are not in the string, like '=',':' etc.
            >
            >So a list like miva_array_deserialize('abc,def,aaa,cde') gives you the
            >array [1]=abc,[2]=def,[3]=aaa,[4]=cde
            >
            >
            >
            >Hope that helps,
            >
            >Markus
            >
            >
            >
            >
            >
            >
            >
            >
            >
            >
            >-----Original Message-----
            >From: [email protected] [mailto:[email protected]] On
            >Behalf Of [email protected]
            >Sent: Friday, January 28, 2005 4:41 PM
            >To: [email protected]
            >Cc: [email protected]
            >Subject: [meu] Re: Dynamic Arrays and miva_variable_value()
            >
            >I got it solved. Thanks to everyone that posted.
            >
            >There seems to be a problem (at least on my site) with the handling of
            >structures by miva_variable_value(). I finally realized (duh) that
            >since I'm using a Pseudo Array anyway I could just use a Pseudo Structure
            as well.
            >
            ><mvassign name="l.cat_var" value="1_1"> <mvassign
            >name="g.cattreeid_1_1" value="204">
            > <MvASSIGN NAME="l.cat" VALUE="{ miva_variable_value('g.cattreeid_' $
            >l.cat_var) }">
            > <MvEVAL EXPR="{l.cat}">
            >
            >My "array" will contain similarly named g.cattreename_ and
            >g.cattreecode elements.
            >
            >Let me explain l.cat_var" value="1_1
            >
            >Since I can't know how deep the tree is g.cattreeid_1, g.cattreeid_2,
            >g.cattreeid_3 and so on contain the top level category id's.
            >g.cattreeid_1_1, _1_2, _1_3 and so on is the branch below the first top
            >level category. g.cattreeid_4_4_3_1 would be a branch 4 levels deep
            >starting at the 4th top category, 4th parent category, 3rd child
            >category, 1st grandchild etc. As I build the array, I keep track of the
            >depth of each level in a stack array and call a recursive routine to
            >populate all the branches. a Multi dimensional array would have been
            >way more convient to code (as I did on the first crack at this) but
            >Mivascript arrays can't be re-sized and retain their values. So you
            >would have to "pick" an arbitrary depth up front and/or pass a fixed depth
            to the function.
            >
            >
            >
            >Scot Ranney [email protected] Wrote:
            >>
            >>Did you get it working?
            >>
            >>The code below basically does what you are looking for from what I
            >>could glean from your emails.
            >>
            >><MvCOMMENT>Set l.cat_var to: 1_1</MvCOMMENT> <MvASSIGN NAME =
            >>"l.cat_var" VALUE = "{ '1_1' }">
            >>
            >><MvCOMMENT>asssign 12345 to "g.cattree_1_1:id"</MvCOMMENT> <MvASSIGN
            >>NAME = "{ 'g.cattree_' $ l.cat_var $ ':id' }" VALUE = "{ '12345' }">
            >>
            >><MvCOMMENT>Create your category variable string</MvCOMMENT> <MvASSIGN
            >>NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $ ':id' }">
            >>
            >><MvEVAL EXPR = "{'l.cat_string: ' $ l.cat_string $ '
            '}">
            >>
            >><MvCOMMENT>Assign l.cat_id the value of l.cat_string
            >>(12345)</MvCOMMENT> <MvASSIGN NAME="l.cat_id" VALUE="{
            >>miva_variable_value(l.cat_string)}">
            >>
            >><MvCOMMENT>Evaluate the data</MvCOMMENT> <MvEVAL EXPR = "{'Data: ' $
            >>l.cat_id}">
            >>
            >>Scot
            >><A HREF ="http://www.scotsscripts.com">http://www.scotsscripts.com</A>
            >>
            >>Ray Yates wrote:
            >>> MivaScript's array handling seems to be pretty strangely
            >>> implemented or else I'm just dumb. I can't figure out how to do
            >>> this with the
            >>> miva_variable_value() function or macro's. Neither seem to work
            >>> with structured arrays.
            >>>
            >>> I have a situation where I can't know how many dimensions my array
            >>> will require beforehand. I'm loading the entire category tree into a
            >>> structure and since there is no way to re-dimension an array and
            >>> retain it's values I've been coding using the old techniques
            >>> formerly
            >supported using macro's.
            >>>
            >>> I'm using this structure g.cattree_1_1_n:name, g.cattree_1_1_n:id,
            >>> g.cattree_1_1_n:code.
            >>> Top level category: g.cattree_1:id, Parent level category:
            >>> g.cattree_1_1:id Child level category:
            >>> g.cattree_1_1_1:id and so on for as many levels as needed.
            >>>
            >>> Where l.cat_var is a string in the form "1_1", I have successfully
            >>> stored data in this pseudo array using this technique.
            >>> <MvASSIGN NAME="l.cat" VALUE="{ 'g.cattree_' $ cat_var }">
            >>> <MvASSIGN NAME="{ l.cat }" MEMBER="id" VALUE="{ Categories.d.id }">
            > >>
            >>> BUT, I can't get the data back out.
            >>> Again, where l.cat_var is t string "1_1" the assignment below
            >>> produces the string "g.catree_1_1:id"
            >>> <MvASSIGN NAME="l.cat_string" VALUE="{ 'g.cattree_' $ l.cat_var $
            >>> ':id' }">
            >>>
            >>> This assignment fails to do anything...
            >>> <MvASSIGN NAME="l.cat_id" VALUE="{ miva_variable_value(l.cat_string)
            >
            >>> }">
            >>>
            >>> However, this assignment works!
            >>> <MvASSIGN NAME="l.cat_id" VALUE="{ g.catree_1_1:id }">
            >>>
            >>> Question:
            >>> Once I have created this string "g.catree_1_1:id" as the name if a
            >>> variable that holds Categories.d.id, how do I use that string to get
            >>> the id stored in a simple variable?
            >>>
            >>> Comment:
            >>> I've already tried <MvEVAL EXPR="{[l.cat_string]}"> exactly like
            >>> the documentation shows.
            >>> The compiler produces this error. Found unexpected "" in expression
            >>>
            >>> Ray Yates
            >>>
            >>>
            >>>
            >>> I eventually figured out
            >>>
            >>>
            >>> Ray Yates
            >>> <A HREF
            >>> ="<A HREF ="http://www.flyinghands.com">http://www.flyinghands.com</A>">http://www.flyinghands.com">http://www.flyinghands.com</A></A>
            >>>
            >>>
            >>
            >--
            >From: Ray Yates <[email protected]>
            >

            Comment


              #7
              Re: Dynamic Arrays and miva_variable_value()



              On Sat, 29 Jan 2005 17:07:21 -0700, jim cranford <[email protected]>
              gave utterance to the following:

              > Howdy Markus,
              >
              > I'm jumping into these arrays... look like they should be slick, but i'm
              > having a hard time making miva_variable_value() work inside
              > miva_array_max().
              >
              > I've been working with the sameple code you posted and this:
              > <MvASSIGN NAME = "l.max" VALUE = "{
              > miva_array_max(miva_variable_value('g.assignment:' $l.parent_id))}" >
              >
              > gets me this...
              >
              > Expression Error: Parameter 'aggregate' in call to function
              > 'miva_array_max' expects a variable, found an expression or constant
              >
              > Does this only work in compiled scripts?
              >
              It shouldn't work at all unless g.assignment is set up to be a structure
              of variables which contain array names.
              miva_array_max expects an array name as its argument:
              miva_variable_value('g.assignment:'$l.parent_id)
              will under most circumstances evaluate as a string or numeric value.
              --
              Richard Grevers
              Between two evils always pick the one you haven't tried



              Comment


                #8
                Re: Dynamic Arrays and miva_variable_value()



                Hi Richard,

                "It shouldn't work at all unless g.assignment is set up to be a structure of
                variables which contain array names."

                That is exactly what it is (or supposed to be). During the initial loop
                through the category table, it creates a structure for each ID
                (g.assigment:$d.id) and then adds a classic array of all matching child IDs
                for this particular member. Using miva_array_max(
                miva_variable_value('g.assignment:'$d.id))+1 is the shortest way to create
                an valid (positive integer) index without initiating yet another variable.


                markus



                -----Original Message-----
                From: [email protected] [mailto:[email protected]] On Behalf
                Of Richard Grevers
                Sent: Saturday, January 29, 2005 7:38 PM
                To: [email protected]
                Subject: Re: [meu] Re: Dynamic Arrays and miva_variable_value()

                On Sat, 29 Jan 2005 17:07:21 -0700, jim cranford <[email protected]> gave
                utterance to the following:

                > Howdy Markus,
                >
                > I'm jumping into these arrays... look like they should be slick, but
                > i'm having a hard time making miva_variable_value() work inside
                > miva_array_max().
                >
                > I've been working with the sameple code you posted and this:
                > <MvASSIGN NAME = "l.max" VALUE = "{
                > miva_array_max(miva_variable_value('g.assignment:' $l.parent_id))}" >
                >
                > gets me this...
                >
                > Expression Error: Parameter 'aggregate' in call to function
                > 'miva_array_max' expects a variable, found an expression or constant
                >
                > Does this only work in compiled scripts?
                >
                It shouldn't work at all unless g.assignment is set up to be a structure of
                variables which contain array names.
                miva_array_max expects an array name as its argument:
                miva_variable_value('g.assignment:'$l.parent_id)
                will under most circumstances evaluate as a string or numeric value.
                --
                Richard Grevers
                Between two evils always pick the one you haven't tried



                Comment


                  #9
                  Re: Re: Dynamic Arrays and miva_variable_value()



                  Thanks. I will study this in greater detail.

                  I don't know how efficient MivaScript arrays are. In some languages, memory for the entire array is allocated at once whether the element is used or not. For multi dimensional arrays on a busy web server, that could be very inefficient indeed. The pseudo array I'm using only allocates memory as needed and seems quite fast. Some simple string manipulation creates the variable name where the data is assigned and retrieved.

                  I'm using the Miva functions below in a loop inside my low level function.
                  Customer_Category_FindFirst_Parent()
                  Customer_Category_FindNext_Parent()
                  This retrieves each branch of the tree. I loop through each branch recursively following any child branches found, in turn constructing the next branch where g.cattreeid_1 is the first top level _1_1 is the first second level and so on. Obviously, sorting such a structure could be problematic, but since I am constructing the data in the order assigned in Merchant, sorting is un-necessary.

                  I therefore have three loops, Construct a branch, construct all branches recursively, and display the data. After reading your post I realize it might be possible to do the entire process including display in only 1 recursive loop and eliminate the array process altogether. I will probably have to access the data directly instead of using the merchant function. (It seems “FindFirst” and “FindNext” get confused easily) I plan to explore that possibility tonight

                  Thanks again for the help.
                  Ray

                  >MvMarkus [email protected] Wrote:
                  >
                  >Hi Ray,
                  >
                  >" a Multi dimensional array would have been way more convient to code (as I
                  >did on the first crack at this) but Mivascript arrays can't be re-sized and
                  >retain their values. So you would have to "pick" an arbitrary depth up front
                  >and/or pass a fixed depth to the function."
                  >
                  >There are several ways to resize arrays and keeping their values. Also using
                  >MD-arrays/structures is definitely easier and faster. In any event you might
                  >need to run two full loops through your category array.
                  >
                  >Imagine you have a table with an ID, PARENT and label, where PARENT refers
                  >to ID.
                  >
                  >First create two arrays/structures with all records.
                  >
                  > <MvWHILE EXPR = "{ NOT d.eof }">
                  >
                  > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values)+1 }"
                  >MEMBER="ID" VALUE = "{ d.id }" >
                  > <MvASSIGN NAME = "g.values" INDEX="{miva_array_max(g.values) }"
                  >MEMBER="LABEL" VALUE = "{ d.label }" >
                  >
                  > <MvIF EXPR = "{ NOT d.parent }" >
                  > // if the record is the top level and has no parent
                  > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
                  >miva_array_max(g.values) }" >
                  > <MvMEMBER NAME="ROOT">
                  > <MvDIMENSION INDEX="{
                  >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
                  > </MvASSIGNARRAY>
                  > <MvELSE>
                  > <MvASSIGNARRAY NAME = "g.assignment" VALUE = "{
                  >miva_array_max(g.values) }" >
                  > <MvMEMBER NAME="{d.parent}">
                  > <MvDIMENSION INDEX="{
                  >miva_array_max(miva_variable_value('g.assignment: '$d.parent)+1 }">
                  > </MvASSIGNARRAY>
                  > </MvIF>
                  > <MvSKIP>
                  ></MvWHILE>
                  >
                  > // Start a recursive functioncall, beginning with the
                  >g.assignement:ROOT-level
                  >
                  ><MvEVAL EXPR = "{ display_branches('root') }" >
                  >
                  >This is then the function that displays the tree.
                  >
                  ><MvFUNCTION NAME = "display_branches" PARAMETERS="parent_id"
                  >STANDARDOUTPUTLEVEL = "html,text,compresswhitespace">
                  > //get the count of the members on this level
                  > <MvASSIGN NAME = "l.max" VALUE = "{ miva_array_max(
                  >miva_variable_value('g.assignment:'$l.parent_id ) }" >
                  >
                  > <ul>
                  > <MvASSIGN NAME = "l.a" VALUE = "1" >
                  > <MvWHILE EXPR = "{ l.a LE l.max }">
                  >
                  > // Get the current ID, for clarity reason here.
                  > <MvASSIGN NAME = "l.id" VALUE = "{
                  >miva_variable_value('g.assignment:'$l.parent_id $'['$l.a$']') }" >
                  >
                  > [*]<MvEVAL EXPR = "{ g.values[l.id]:ID }" >....<MvEVAL EXPR
                  >= "{ g.values[l.id]:LABEL }" >
                  >
                  > <MvIF EXPR = "{ miva_variable_value(
                  >'g.assignment:'$l.id$'[1]') }">
                  > // if a child exist calls the same function again , but this
                  >time (instead of using 'root' as the parameter, it uses the ID.
                  >
                  > <MvEVAL EXPR = "{ display_branches(miva_variable_value(
                  >'g.assignment:'$g.values[l.id]:ID$'[1]') ) }" >
                  > </MvIF>
                  >
                  > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" >
                  > </MvWHILE>
                  > [/list]
                  ></MvFUNCTION>
                  >
                  >
                  >
                  >This is written blindly and NOT TESTED, but I have used this technique
                  >numerous times and it works quite well. It is however very important to add
                  >some security measures into it, to a.) prevent infinitive recursive
                  >functioncalls and b.) to avoid non-integer values for l.id (in the
                  >array-indices of g.values[l.id]:ID in display_branches()).
                  >
                  >The nice thing this technique allows with a little modification to add
                  >complex sorting of your trees, independently of a database index, and or
                  >expanded or collapsed branches.
                  >
                  >
                  >...
                  >You should also look into the functions miva_array_deserialize() and
                  >miva_array_collapse(). Both can be very helpful.
                  >
                  >For example, instead of using my "miva_array_max(g.values)+1" , you could
                  >write a simple, comma separated string, and then at the end deserialize it,
                  >which then returns a real array. You just have to make sure that certain
                  >characters are not in the string, like '=',':' etc.
                  >
                  >So a list like miva_array_deserialize('abc,def,aaa,cde') gives you the array
                  >[1]=abc,[2]=def,[3]=aaa,[4]=cde
                  >
                  >
                  >
                  >Hope that helps,
                  >
                  >Markus
                  --
                  From: Ray Yates <[email protected]>

                  Comment


                    #10
                    Re: Re: Dynamic Arrays and miva_variable_value()



                    A quick FYI.

                    Miva Script arrays are sparse. If you have an array like this:

                    <MvASSIGN NAME=3D"l.years" INDEX=3D"1776" VALUE=3D"American
                    Revolution">
                    <MvASSIGN NAME=3D"l.years" INDEX=3D"1996" VALUE=3D"eCommerce
                    Revolution">

                    You are only taking up the space in memory needed for those two
                    items, not for 1996 items.

                    - Jeff Huber
                    President 4TheBest eCommerce Solutions
                    http://4TheBest.com
                    [email protected]
                    Office: 760-742-1469
                    Cell: 760-445-8454
                    =20

                    -----Original Message-----
                    From: [email protected]
                    [mailto:[email protected]] On Behalf Of
                    [email protected]
                    Sent: Saturday, January 29, 2005 8:44 PM
                    To: [email protected]
                    Subject: [meu] Re: Re: Dynamic Arrays and miva_variable_value()


                    Thanks. I will study this in greater detail.=20

                    I don't know how efficient MivaScript arrays are. In some
                    languages, memory for the entire array is allocated at once
                    whether the element is used or not. For multi dimensional arrays
                    on a busy web server, that could be very inefficient indeed. The
                    pseudo array I'm using only allocates memory as needed and seems
                    quite fast. Some simple string manipulation creates the variable
                    name where the data is assigned and retrieved.

                    I'm using the Miva functions below in a loop inside my low level
                    function.=20
                    Customer_Category_FindFirst_Parent()
                    Customer_Category_FindNext_Parent()
                    This retrieves each branch of the tree. I loop through each
                    branch recursively following any child branches found, in turn
                    constructing the next branch where g.cattreeid_1 is the first top
                    level _1_1 is the first second level and so on. Obviously,
                    sorting such a structure could be problematic, but since I am
                    constructing the data in the order assigned in Merchant, sorting
                    is un-necessary.=20

                    I therefore have three loops, Construct a branch, construct all
                    branches recursively, and display the data. After reading your
                    post I realize it might be possible to do the entire process
                    including display in only 1 recursive loop and eliminate the
                    array process altogether. I will probably have to access the data
                    directly instead of using the merchant function. (It seems
                    "FindFirst" and "FindNext" get confused easily) I plan to explore
                    that possibility tonight

                    Thanks again for the help.
                    Ray


                    Comment

                    Working...
                    X