|
Forum List • Thread List • Refresh • New Topic • Search • Previous • Next 1 |
1. Array key search #1337 |
If I use a 2 dimensional array to store a data table, I want the first tail name as its key, i.e.:key1 key2 key3
---------------------------
data11 data12 data13
data21 data22 data23
data.key1.1='data11'
data.key1.2='data21'
data.key2.1='data12'
data.key2.2='data22'
data.key3.1='data13'
data.key3.2='data23' Now, if I want to search and delete the whole column of key2, what's the easiest, most efficient way? |
2. Re: Array key search #1338 Posted by: 2002-11-12 14:05:56 |
I think that your best bet would be to use a separate 1-dimensional array for each column. Form a stem name that tells you the column as so:column1.1 = 'data11'
column1.2 = 'data21'
column2.1 = 'data12'
column2.2 = 'data22'
column3.1 = 'data13'
column3.2 = 'data23' That way, if you want to delete column2, all you need do is:DROP column2. And if you want to enumerate all of the items under column2, you can use a DO OVER loop.
DO OVER is a way to loop over all variables that use a certain stem, without knowing exactly how many, and what, tail names use that stem. For example, if you want to find out the names of all variables that use the stem column2., you can do: DO i OVER column2.
SAY column2.i
END Each time around the loop, i will be set to the next tail name that uses "column2.". For example, let's say you have the following: mystem.name = "Jeff"
mystem.1 = 100
mystem.first.second = "Some string"
DO i OVER mystem.
SAY mystem.i
END The first time through the DO OVER loop, the variable i is set to the value "name". That's because name is the first tail that uses MyStem as its stem. So you actually SAY the value of MyStem.name and "Jeff" gets displayed. The second time through the DO OVER loop i is set to the value "1". That's because 1 is the second tail that uses MyStem as its stem. So you actually SAY the value of MyStem.1 and "100" gets displayed. The third time through the DO OVER loop, the variable i is set to the value "first.second". That's because first.second is the third tail that uses MyStem as its stem. So you actually SAY the value of MyStem.first.second and "Some string" gets displayed. Then the DO OVER loop ends because there are no more tail names that use MyStem. In other words, DO OVER can be used to enumerate all of the tails that use a given stem, and thereby access the values of each of those variables.
The only caveat is that there is no guaranteed order to enumerating the tails. For example, they are not enumerated in alphabetical order. So, if you need a specific order, then this is not going to work for you. |
3. DO OVER limitations #1339 |
Does DO OVER work only for 1-dimensional arrays? If I use my above array, and do:DO i OVER data.
SAY data.i
END It gives me all 9 elements.
But a 1-dimensional array can't solve my problem. I use a variable to hold the total count of columns. And I want a 2-dimensional array with descriptive names (ie, not numbers) as subscripts (tails), such as: key1, key2, anotherKey, etc. I don't want to use numbers for tails. |
4. DO OVER, DROP, assignment limitations #1340 Posted by: 2002-11-13 14:49:37 |
For most interpreters, DO OVER works only with one-dimensional arrays because that's the way that Object REXX works (and IBM's Object REXX is where the DO OVER feature first appeared). Reginald's DO OVER will work with compound variables. (And many interpreters do not even support DO OVER).
But note also thatDROP data.key2. won't DROP all compound variables that use data.key2. as their root.
Neither willdata.key2. = "Empty" Initialize all compound variables that use data.key2. as their root.
These DROP and assignment "shortcuts" work only with one-dimensional arrays. |
5. Re: DO OVER, DROP, assignment limitations #1341 |
Yes, I noticed the limitations with array DROP and initialization.
Can these be changed? |
6. Re: Array key search #1342 Posted by: 2002-11-13 17:39:30 |
I don't know as if I'd want to change the way that DROP and variable assignment work since those are well-standardized behaviors among all REXX interpreters. But DO OVER is not really a REXX standard. So, Reginald supports DO OVER on compound variables (which Object REXX doesn't).
So Reginald allows DO OVER to work with two (or more) dimensional arrays. You can do:DO i OVER data.key2.
SAY data.key2.i
END Therefore, you can simulate the DROP "shortcut" yourself as so:
DO i OVER data.key2.
DROP data.key2.i
END There's not a way to perfectly simulate the assignment shortcut. You can do:
DO i OVER data.key2.
data.key2.i = 'empty'
END But one difference here is that variables which haven't yet been given a value still default to their name upper-cased. So now you have different values for cells which haven't yet been created, and ones which are marked as "empty". That may not be a problem for you. If it is, there is something you can do.
If you need to mark a "cell" as "empty", I think that you should just DROP it. Then you can always use SYMBOL() to test if the cell is empty, and use INTERPRET if you have to create the variable name on-the-fly.
DO i = 1 TO 4
INTERPRET "test = SYMBOL('data.key2." || i || "')"
IF test == 'VAR' THEN SAY "Cell is not empty"
ELSE SAY "Cell is empty"
END
DO i = 1 TO totalrows
INTERPRET "test = SYMBOL('data.key" || i || ".1')"
IF test == 'VAR' THEN SAY "Cell is not empty"
ELSE SAY "Cell is empty"
END The advantage of the above is that, cells which are not yet created are the same as cells which are DROP'ed -- ie, "empty". So you don't really need any "default value" to mark a cell as empty. It is automatically empty if you haven't yet assigned it a value. Otherwise, when you DROP it, it becomes empty again. |
7. Re: Array key search #1347 |
Still not a very useful DO OVER:data.key1.1='data11'
data.key1.2='data21'
data.key2.1='data12'
data.key2.2='data22'
data.key3.1='data13'
data.key3.2='data23' DO i OVER data.
DO j OVER i.
SAY i j data.i.j
END
END In this situation, I want to enumerate the subkeys of i., which should be key1, key2, key3, etc., but the above code displays nothing at all. |
8. Re: Array key search #1768 |
The reason why nothing is being displayed is because there is no stem named i. used in your script. It has no existing tails. So the inside loop (with the SAY instruction) never gets executed at all.
I don't have any clue what you're really trying to do. I assume that you're trying to make some sort of 2-dimensional "grid", but I have no idea what the specifications are. I get the impression that it has a variable number of rows, as well as a variable number of columns, but I'm guessing here. And I think that some of the "cells" can be empty, but again, I'm guessing here. And I think that there are a large number of cells, and therefore there could be a large number of empty ones. So maybe you're trying to use DO OVER to enumerate only those cells that aren't empty (ie, ones that have been assigned a value) in the hopes of saving yourself the trouble of having to maintain a count of how many cells (columns) are in each row, or maybe how many rows there are. I'm guessing here. I don't know as if you're maintaining counts of how many columns and rows there are. And maybe you're even hoping to avoid going through every possible cell to check if it's "empty" or has data when you loop through the data. Again, I'm guessing because you haven't said what it is you're trying to accomplish with DO OVER. (You do realize that if you need to traverse a row or column in order, DO OVER will never work for you? DO OVER will enumerate variables in no particular order. Again, I don't know as if this is needed, because you haven't said).
data.1.1='data11'
data.1.2='data21'
data.2.1='data12'
data.2.2='data22'
data.3.1='data13'
data.3.2='data23'
SAY "Which column would you like to list (1, 2, or 3)?"
PULL col
DO i OVER data.col.
SAY data.col.i
END
SAY "Which row would you like to list (1, 2, or 3)?"
PULL row
row = '.' || row
LENGTH = LENGTH(row)
DO i OVER data.
IF RIGHT(i, length) = row THEN SAY data.i
END
numofrows = 3
numofcols = 2
DO i = 1 TO numofcols
DO j = 1 TO numofrows
CALL CHAROUT(,data.j.i)
CALL CHAROUT(," ")
END
CALL CHAROUT(,"0D0A"x)
END
EXIT |
9. Re: Array key search #1769 |
Guidance writes:
I want a 2-dimensional array with descriptive names (ie, not numbers) as subscripts (tails), such as: key1, key2, anotherKey, ...
My real task is to delete a certain column specified by its tail name, not index number. I'm trying to enumerate each element by traversing whole array.
I hope the first (outer) DO OVER can tell me all the first subscript (tail), and the second (inner) one tells the second one's, etc. I don't care about the order. Then I can compare the tail and decide to DROP it or not. I suppose it's similiar to the "foreach" statement in PHP or VB. |
10. Re: Array key search #1770 |
No problem.
data.key1.1='data11'
data.key1.2='data21'
data.key2.1='data12'
data.key2.2='data22'
data.key3.1='data13'
data.key3.2='data23'
again:
SAY "Which column would you like to list (1, 2, or 3)?"
PULL col
IF DATATYPE(col, 'W') == 1 THEN DO
SAY "You didn't follow the instructions. I said to enter a number."
SIGNAL again
END
col = "KEY" || col
DO i OVER data.col.
SAY data.col.i
END
EXIT One note on the above: Tail names are case-sensitive when not quoted. So that is why I uppercase the variable name KEY when I *did* put it in quotes:col = "KEY" || col I want to make sure that I reference "KEY" (not "Key" nor "key", etc) because my reference needs to be to the same Key variable used in other instructions such as:data.key1.1 = 'data11' REXX automatically uppercases any variable name not in quotes, so the above line is actually translated by REXX into:data.key1.1 = 'data11' And although data.KEY1 may be the same variable as DATA.KEY1 (ie, the stem part of any variable is always case-insensitive), DATA.KEY1 is not the same as DATA.Key1 (ie, the tail names are case sensitive). |
11. Re: Array key search #1771 |
Guidance writes:
If I do this:DO i OVER data.
PARSE VAR i subdata '.'
DO j OVER data.subdata.
SAY data.subdata.j
END
END The first DO OVER enumerates all 6 elements, not limited within first tail only, thus I got total 12 SAYs.
Your example works. But I want to use an arbitrary name for my tails (not a specific format to every key name). My above example displays all 12 variables that reference data. as their stem. How can instead just reference the variables using one of the key tails? |
12. Re: Array key search #1772 |
Just use the example I showed you, except instead of getting the "name" from the user (which I did just to show you how to dynamically, and therefore, arbitrarily get some variable name), assign the desired tail name yourself. The only thing you have to be careful about is to make sure that you upper case that column (tail) name (which you can do with the TRANSLATE function if necessary).data.key1.1='data11'
data.key1.2='data21'
data.keygg2.1='data12'
data.keygg2.2='data22'
data.keytat3.1='data13'
data.keytat3.2='data23'
col = "KEYGG2"
DO i OVER data.col.
SAY data.col.i
END
EXIT |
13. Re: Array key search #1773 |
Guidance writes:
I would like to give a PHP code for illustration:$data['key1'][1]='data11';
$data['key1'][2]='data21';
$data['keygg2'][1]='data12';
$data['keygg2'][2]='data22';
$data['keytat3'][1]='data13';
$data['keytat3'][2]='data23';
foreach ($data as $i) // here $i will be a one-dim sub-array WITH 2 elements inside
{
foreach ($i as $j)
{
echo $j;
}
} Should output these 6 elements.
If I want to delete column keygg2:foreach ($data as $key => $i)
{
IF ($key=='keygg2') unset($data[$key]);
} If want to delete row 2:foreach ($data as $key1 => $i)
{
foreach ($i as $key2 => $j)
{
IF ($key2==2) unset($data[$key1][$key2]);
}
} Seems hard to write the equivalent in Rexx. |
14. Re: Array key search #1774 |
Here it is:data.key1.1 = 'data11'
data.key1.2 = 'data21'
data.keygg2.1 = 'data12'
data.keygg2.2 = 'data22'
data.keytat3.1 = 'data13'
data.keytat3.2 = 'data23'
colname = "KEYGG2"
DO i OVER data.colname.
DROP data.colname.i
END
data.key1.1 = 'data11'
data.key1.2 = 'data21'
data.keygg2.1 = 'data12'
data.keygg2.2 = 'data22'
data.keytat3.1 = 'data13'
data.keytat3.2 = 'data23'
rowname = 2
DO i OVER data.
PARSE VAR i col '.' row '.' .
IF row == rowname THEN DROP data.i
END
That's pretty easy to me. And note that you can use names for your rows as well as columns. For example, you can have a row named 'MyRow' as so:data.key1.1 = 'data11'
data.key1.myrow = 'data21'
data.keygg2.1 = 'data12'
data.keygg2.myrow = 'data22'
data.keytat3.1 = 'data13'
data.keytat3.myrow = 'data23'
DO i OVER data.
PARSE VAR i col '.' row '.' .
IF row == myrow THEN DROP data.i
END |
Forum List • Thread List • Refresh • New Topic • Search • Previous • Next 1 |