Date: Wed, 29 Sep 2004 14:26:07 -0400
Reply-To: "Fehd, Ronald J." <RJF2@CDC.GOV>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Fehd, Ronald J." <RJF2@CDC.GOV>
Subject: Re: %IF with IN condition?
Content-Type: text/plain; charset="us-ascii"
ladies and gentlemen,
the bar has been raised, and attained.
excellent work, Chang! <applause>
[X] explanatory comments
[X] strong code:
good parameter checking
intelligent note, warning, & error messages
[X] test data
[X] log of test data
Ron Fehd the documentation maven CDC Atlanta GA USA
> -----Original Message-----
> From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On
> Behalf Of Chang Y. Chung
> Sent: Wednesday, September 29, 2004 2:16 PM
> To: SAS-L@LISTSERV.UGA.EDU
> Subject: Re: %IF with IN condition?
>
>
> On Tue, 28 Sep 2004 16:18:37 -0400, Talbot Michael Katz
> <topkatz@MSN.COM>
> wrote:
>
> >Chang, once again I applaud your cleverness. I originally
> had rejected
> the
> >idea of trying to use %INDEX because of the possibility of getting a
> >false positive with a substring match, but your trick of
> encapulating
> >both sides of the comparison objects with delimiters neatly
> takes care
> >of the substring match problem -- most of the time.
> Unfortunately, it
> >can break down if the item string actually contains a delimiter
> >character.
>
> Hi, TMK,
>
> I think bullet-proofing a macro is very hard. Still, it
> should be much easier than idiot-proofing (which I know for
> sure that is impossible). So I tried. Hope you find it useful.
>
> Cheers,
> Chang
>
> P.S. Now, I see my new pc has such a, cool,
> sliding-out-at-the-touch-of- button cup-holder. What I don't
> get is: why is it so flimsy?! It looks like it could barely
> hold a single CD-ROM...
>
>
> <sasl:code>
> %macro inList(item, in=, dlm=%str(, ));
> /*
> returns 1 if &item. is found in a &dlm. delimited
> list &in., otherwise returns 0.
>
> NOTES:
>
> The default delimiters are comma^s and blanks.
>
> Multiple conjecutive delimiters are considered as a
> single delimiter, even though they are different
> characters.
>
> The delimiters found in the &item. will be compressed out.
>
> returns error message when &item. resolves to nothing,
> also when dlm= is specified and resolves to nothing.
>
> returns 0 (false) and a note when the &in. is nothing.
>
> by chang y. chung on 2004-09-29
> */
> %local dlm1 dimLen i d r;
>
> %if "%superq(dlm)"="" %then %do;
> %put ERROR: (inList) dlm (delimiters) cannot be nothing;
> %goto exit;
> %end;
>
> %let dlm1 = %qsubstr(%superq(dlm),1,1);
> %let dlmLen = %length(%superq(dlm));
>
> %let item = %qsysfunc(compress(%superq(item),%superq(dlm)));
> %if "%superq(item)"="" %then %do;
> %put ERROR: (inList) item may be nothing or has only the
> delimiters.;
> %goto exit;
> %end;
>
> %if "%superq(in)"="" %then %do;
> %put NOTE: (inList) an empty in= list.;
> %let r = 0;
> %goto returnValue;
> %end;
>
> %if &dlmLen. >= 2 %then %do;
> %do i = 2 %to &dlmLen.;
> %let d = %qsubstr(%superq(dlm),&i.,1);
> %let in = %qsysfunc(translate(%superq(in),%superq(dlm1),%superq
> (d)));
> %end;
> %end;
>
>
> %let item = &dlm1.&item.&dlm1.;
> %let in = &dlm1.&in.&dlm1.;
>
> %if %index(%superq(in), %superq(item)) %then
> %let r=1; /* true */
> %else
> %let r=0; /* false */
>
> %returnValue:
> %*;&r.
>
> %exit:
> %mend;
>
> %macro inList_test;
> %put should be 0***%inlist(1, in=2 3)***;
> %put should be 1***%inlist(2, in=2 3)***;
> %put should be 0***%inlist(%str( 2 ), in=%str( 2 3 ),
> dlm=%str(,))***;
> %put should be 1***%inlist(%str( 2 ), in=%str(2 3))***;
> %put should be 0***%inlist(2, in=)***;
> %mend;
> %*inList_test; /* un-comment to test */
> /* on log
> should be 0***0***
> should be 1***1***
> should be 0***0***
> should be 1***1***
> NOTE: (inList) an empty in= list.
> should be 0***0***
> */
> </sasl:code>
>
|