/******************* URBAN INSTITUTE MACRO LIBRARY *********************
: ListNoDup
Macro: Autocall macro returns list with duplicate entries
Description
removed.
: Function
Use
: Peter Tatian
Author
***********************************************************************/
ListNoDup(
%macro /* List of items */
list, delim=%str( ) /* Delimiter for list (def. blank char) */
);
/*************************** USAGE NOTES *****************************
:
SAMPLE CALLListNoDup( A.B.C.D.E.B.F.A.C.G, delim=. )
%
returns unduplicated list A.B.C.D.E.F.G*********************************************************************/
/*************************** UPDATE NOTES ****************************
02-01-16 PAT Corrected error when list has more than 2 duplicates of
same item.*********************************************************************/
***** ***** ***** MACRO SET UP ***** ***** *****;
%
%local ListNoDup scanlist target i v;
***** ***** ***** ERROR CHECKS ***** ***** *****;
%
%if &delim = { or &delim = } %then %do;
err_mput( macro=ListNoDup, msg=Curly braces { } cannot be used as list delimiters. )
%
%goto exit;
%end;
%if %index( &list, {{bol}} ) > 0 or %index( &list, {{eol}} ) > 0 %then %do;
err_mput( macro=ListNoDup, msg=The text "{{bol}}" or "{{eol}}" must not appear in the list. )
%
%goto exit;
%end;
***** ***** ***** MACRO BODY ***** ***** *****;
%
= ;
%let ListNoDup = {{bol}}&delim&list&delim{{eol}};
%let scanlist %let target = %scan( &scanlist, 2, &delim );
%do %while ( %length( &target ) > 0 and &target ~= {{eol}} );
** Add item to unduplicated list **;
%%if %length( &ListNoDup ) = 0 %then
= ⌖
%let ListNoDup else
%= &ListNoDup&delim⌖
%let ListNoDup
** Remove all other occurances of item **;
%
= 1;
%let i %let v = %scan( &scanlist, &i, &delim );
= ;
%let newscanlist
%do %until ( &v = );
%if &v ~= &target %then %do;
%if %length( &newscanlist ) = 0 %then
= &v;
%let newscanlist else
%= &newscanlist&delim&v;
%let newscanlist
%end;
%let i = %eval( &i + 1 );
%let v = %scan( &scanlist, &i, &delim );
%end;
= &newscanlist;
%let scanlist %let target = %scan( &scanlist, 2, &delim );
%end;
%let ListNoDup = %unquote( &ListNoDup );
&ListNoDup
:
%exit
***** ***** ***** CLEAN UP ***** ***** *****;
%
%mend ListNoDup;
/************************ UNCOMMENT TO TEST ***************************
*options mprint symbolgen mlogic;
"K:\Metro\PTatian\UISUG\Uiautos";
filename uiautos =(uiautos sasautos);
options sasautos** This test generates an error **;
%= A{B{C{D{E{B{F{A{C{G;
%let list %let undup = [%ListNoDup( &list, delim={ )];
%put _user_;** This test generates an error **;
%= A B {{bol}} C D;
%let list %let undup = [%ListNoDup( &list )];
%put _user_;= A.B.C.D.E.B.F.A.C.G;
%let list %let undup = [%ListNoDup( &list, delim=. )];
%put _user_;= .A.B.C.D.E.B.F.A.C.G.;
%let list %let undup = [%ListNoDup( &list, delim=. )];
%put _user_;= ..A...B.C..D.E.B.F.A.C.G;
%let list %let undup = [%ListNoDup( &list, delim=. )];
%put _user_;= A B C D E B F A C G;
%let list %let undup = [%ListNoDup( &list )];
%put _user_;%let list = %str( A B C D E B F A C G );
%let undup = [%ListNoDup( &list )];
%put _user_;= A B C AA AAA D E B AA F A AA C G AAAA;
%let list %let undup = [%ListNoDup( &list )];
%put _user_;= 0001 0001 0002 0002 0002 0002 0002 0002 0002 0100;
%let list %let undup = [%ListNoDup( &list )];
%put _user_;/**********************************************************************/
Remove Duplicates from List
Purpose: Autocall macro returns list with duplicate entries removed.