View Full Version : pushing/popping array values
talamar
01-18-07, 07:52 PM
Most other languages allow you to push and pop values off arrays without caring what the index value is, using it more like a list than an array. Can this be done with MIVA?
I noticed in the lack of docs that they don't tell you how to remove items from arrays or structures....
mvmarkus
01-19-07, 10:32 AM
Most other languages allow you to push and pop values off arrays without caring what the index value is, using it more like a list than an array. Can this be done with MIVA?
I noticed in the lack of docs that they don't tell you how to remove items from arrays or structures....
Hi,
To add one to an array:
<MvASSIGN NAME = "l.array" INDEX="{ miva_array_max( l.array)+1}" VALUE = "{ l.value }" >
To remove one, simply set the value to zero. If you want to reset the indices of the following members, you can use miva_array_collapse()
<MvASSIGN NAME = "l.array" INDEX="{ l.index }" VALUE = "" >
<MvASSIGN NAME = "l.foo" VALUE = "{ miva_array_collapse( l.array) }" >
Markus
talamar
01-19-07, 03:58 PM
It sounds plausible, I'll have to try. So if I set all the indices to 0 and then do an eval on the array, it will return 0 (i.e. <MvIF EXPR="{l.array}"> or <MvIF EXPR="{miva_array_max(l.array) eq 0}">)
mvmarkus
01-19-07, 04:31 PM
It sounds plausible, I'll have to try. So if I set all the indices to 0 and then do an eval on the array, it will return 0 (i.e. <MvIF EXPR="{l.array}"> or <MvIF EXPR="{miva_array_max(l.array) eq 0}">)
Hi talamar,
I am not sure if I understand you right. You can't set the index to 0, this will give you a runtime error. You can only set the value to zero; the miva_array_max() may still preserve the number of the highest index.
Markus
talamar
01-19-07, 07:11 PM
What I'm trying to do is create an array, pop some data off, and then test to see if the array is empty. If I am setting values to 0 in the array to simulate a pop, will the array eval to 0 if I test it?
Vic - WolfPaw Computers
01-19-07, 07:13 PM
This will produce the dreaded "Array must be a positive integer" error - which as of Empresa v5.06 is still not fixed.
You have to at least set the array = 1. Meaning your array must have at least one dataset value, who's value can be 0.
It sounds plausible, I'll have to try. So if I set all the indices to 0 and then do an eval on the array, it will return 0 (i.e. <MvIF EXPR="{l.array}"> or <MvIF EXPR="{miva_array_max(l.array) eq 0}">)
RayYates
01-21-07, 07:14 AM
While it might be possible to use miva_array_max(myarray) in combination with miva_array_collapse(myarray) to write Push() and Pop() functions I think simply keeping track of the current index in a global variable would be way more efficient.
<MvFUNCTION NAME="Push" PARAMETERS="value" STANDARDOUTPUTLEVEL="compresswhitespace">
<MvASSIGN NAME="g.ndx" VALUE="{ g.ndx + 1 }">
<MvASSIGN NAME="g.myarray" INDEX="{ g.ndx }"VALUE="{ l.value }">
<MvFUNCRETURN VALUE="{ g.ndx }">
</MvFUNCTION>
<MvFUNCTION NAME="Pop" STANDARDOUTPUTLEVEL="compresswhitespace">
<MvIF EXPR="{ g.ndx GT 0 }">
<MvASSIGN NAME="l.value" VALUE="{ g.myarray[g.ndx] }">
<MvASSIGN NAME="g.ndx" VALUE="{ g.ndx -1 }">
</MvIF>
<MvFUNCRETURN VALUE="{ l.value }">
</MvFUNCTION>
<MvASSIGN NAME="l.foo" VALUE="{ Push('John') }">
<MvASSIGN NAME="l.foo" VALUE="{ Push('Q.') }">
<MvASSIGN NAME="l.foo" VALUE="{ Push('Public') }">
<MvWHILE EXPR="{ g.ndx GT 0 }">
<MvEVAL EXPR="{ Pop() }">
</MvWHILE>
Result: Public Q. John
While you could pass the array variable name to the function if you have several of these stack structures, I don't think the extra complexity would be worth it.
mvmarkus
01-21-07, 10:28 AM
While it might be possible to use miva_array_max(myarray) in combination with miva_array_collapse(myarray) to write Push() and Pop() functions I think simply keeping track of the current index in a global variable would be way more efficient.
Result: Public Q. John
While you could pass the array variable name to the function if you have several of these stack structures, I don't think the extra complexity would be worth it.
Hi Ray,
The difference is probably hardly recognizable, but I am pretty sure that your function is actually less efficient, since it requires a few program steps, memory allocations, functioncalls, where miva_array_max() actually is a straight call to a C function which is usually extremely efficient.
But what is much more important for me is that your function only works for one array in a script (If you need another one, you'd need to write a new function to introduce another counter (g.ndx)) and you need to "protect" g.ndx - meaning to make sure that nowhere else the variable will be used or overwritten.
On the other hand miva_array_collapse() is a bit problematic, because it crashes Empresa on Windows, if you have more than some 12500 members. This bug exists for ages but has obviously never bothered anybody at Miva Corp.
Markus
RayYates
01-22-07, 05:33 AM
I originally conceived this as passing the array index and value as
<MvFUNCTION NAME="Push" PARAMETERS="myarray VAR, ndx VAR, value">
Then the function would be complete portable to use with any single dimensioned aray/stack. But really why even bother? If you alread know ndx why not just access the array directly and incriment or decriment the index.
Also my experience with miva_array_collapse() is that when you assign an 0 or null string to the highest indexed element, it does not necessarily remove/collapse the highest element.
In other words
Assign:
item[1] = value
item[2] = value
item[3] = value
Then:
item[4] = value
item[4] = 0 or item[5] = ""
Then:
miva_array_collapse(item)
miva_array_max(item) will still display 5
at least on the old empressa I'm running.
mvmarkus
01-22-07, 12:27 PM
Hi Ray,
One thing that I always try to avoid as much as possible, is to introduce those free-floating global variables, because in large programs I always loose track of them... or worse some clown could mess with them through the commandline if the variable is not protected.
About miva_array_collapse(): A while ago, Ivo wrote something interesting about how this works, unfortunately, I don't know anymore where to find this. Quite often I use a fairly brutal hack to collapse the array, without using miva_array_collapse():
MvASSIGN="l.array" VALUE="{ miva_array_deserialize(trim(l.array))}">
The trim() breaks the array and turns it into a string, the deserialize turns the string back into an ordered array, with filled dimensions from 1 to xxx. Works good, but of course if the array is very large, this is not really a very efficient way. I never compared the performance to a loop version. Would be interesting to find out.
Markus
RayYates
01-22-07, 04:56 PM
I try to avoid ... free-floating global variables Understood.
If you only have needed a single single stack structure, Push and Pop as defined above lets you ignore the variable names and index values and only deal with the data values. Much more than that and it seems one is adding complexity with very little benifet.
My 2 cents.
vBulletin® v3.7.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.