For some reason my Rexx loop breaks and I don't know why. I'm trying to search a phone number database by ICCID (The identification number for sim cards) and pull the phone number. Here's the loop I have, a little simplified:
(t) is the tab hex code, ICCIDlist.txt contains a list of ICCIDs I'm trying to gather info on
and phonenumberinfo.txt an exhaustive list of ICCIDs and Phone Numbers, looking something like this:
89298374987 409-392-2434
89298765345 409-365-2132
89298334745 409-967-2863
----------------------------------------------
streamICCID=.stream~new('iccidList.txt')
lni = streamICCID~lines
DO i = 1 to lni
ICCID.i = streamICCID~linein(i)
END
soFile=.stream~new('phonenumberinfo.txt')
lno = soFile~lines
DO line = 1 to lno
lnInfo = soFile~linein(line)
lnFind = POS(ICCID.i,lnInfo)
IF lnFind==1 THEN DO
PARSE VAR lnInfo ICCID (t) ownNum.i
i = i + 1; ITERATE
END
ELSE ITERATE
END
DO n = 1 to i
SAY ownNum.n
END
It works for the first one, but as soon as it pulls a phone number from the first ICCID it breaks. I need it to continue until it's done all of the ICCIDs. can anyone help me out?
You're right, this will only work when searching for one ICCID - the last one. As NicC says, you'd probably figure that out if you put a Trace Intermediate
(or just Trace I
) instruction right before your do line = ...
loop. Doing so would show you that you're entering that loop with i
set to the number of the last ICCID you read, and you're counting up from there (i=i+1; ITERATE
).
In other languages, this sort of searching problem is usually solved with two nested loops. After loading the first dataset, you iterate over the second, and for each record, you iterate over the entire first dataset, checking for a match. You're not doing that, you're hand-writing the inner loop, and you're using its index variable (i
) for two different and conflicting purposes (iterating over the first dataset and creating the output dataset).
In Rexx, we wouldn't do that (athough we could). We'd solve this instead by loading the first dataset into an associative array, and then directly accessing it while iterating over the second dataset. That turns an order N-squared algorithm into order N, for a big win.
/* Load the ICCIDs into the "ICCID.*" associative array. The value of
each element we load is TRUE, and the value of anything else is FALSE.
*/
ICCIDlist. = 0 /* Set all the elements to FALSE */
streamICCID=.stream~new('iccidList.txt')
DO i = 1 to streamICCID~lines
item = streamICCID~linein(i)
ICCIDlist.item = 1 /* Set this element to TRUE */
END
/* Search the phone number file for ICCIDs we loaded above and record their presence. */
soFile=.stream~new('phonenumberinfo.txt')
lno = 0
DO line = 1 to soFile~lines
lnInfo = soFile~linein(line)
PARSE VAR lnInfo ICCID (t) phoneNumber
IF ICCIDlist.ICCID THEN DO /* If the ICCIDlist element is TRUE, it was in the first dataset */
lno = lno + 1
ownNum.lno = phoneNumber
END
END
/* Write out the phone numbers for the ICCIDs that we found in both datasets. */
DO n = 1 to lno
SAY ownNum.n
END