
/*** HELP START ***//*

## >>> `%repList()` macro: <<< <a name="replist-macro"></a> #######################

The repList() macro function allows to repeat `T`
times elements of a `L` list, possibly `E` times each element,
separated by string `S`.

See examples below for the details.

The `%repList()` macro executes like a pure macro code.

### SYNTAX: ###################################################################

The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%repList(
   list
 <,times=>
 <,each=>
 <,lenghtOut=>
 <,sep=>
)
~~~~~~~~~~~~~~~~~~~~~~~

**Arguments description**:

1. `list`       - *Required*, a list of elements to be repeated.
                  List can be space or comma-separated. 
                  Elements can be in quotes.
                  For comma-separated list add brackets 
                  e.g., `%repList((A,B,C,D),times=5)`.
                  The list separators are: `<{[( ,;)]}>`.

*  `times=`     - *Optional*, An integer indicating 
                  the number of repetitions.
                  By default set to `1`.


*  `each=`      - *Optional*, A list of integers indicating 
                  the number of repetitions of each element of the list
                  e.g., for a list `A B C` and the `each=2 4` the result 
                  is `A A B B B B C C`. If the number of integers is less
                  then the length of the list values are recycled from 
                  the beginning.
                  By default set to `1`.

*  `lenghtOut=` - *Optional*, An integer indicating 
                  after what the number of repetitions process will stop.
                  By default set to `0` which means "do not stop".

*  `sep=`       - *Optional*, it is a separator printed between 
                  repeated elements. Mnemonics for *space* is `s`,
                  for *comma* is `c`, and for semicolon in `q`.
                  Default value is a single space.

*//*** HELP END ***/




%macro repList(
  list
, times=1
, each=1
, lenghtOut=0
, sep=s
) / minoperator 
des='The %repList() macro function allows to repeat elements of a list given number of times.'
;
%local t e n i j k ce;
%let n = %sysfunc(countw(%superq(list),<{[( ,)]}>%str(;),Q));
%let each =%sysfunc(compress(%superq(each), %str( ),KD));
%let times=%sysfunc(compress(%superq(times),%str( ),KD));
%let ce = %sysfunc(countw(%superq(each),%str( )));

%let lenghtOut=%sysevalf(&lenghtOut. + 0);

%if %superq(sep) NE %then 
%do;
%if %superq(sep) IN (s S) %then %do; %let sep=%str( ); %GoTo _start_;%end;
%if %superq(sep) IN (c C) %then %do; %let sep=%str(,); %GoTo _start_;%end;
%if %superq(sep) IN (q Q) %then %do; %let sep=%str(;); %GoTo _start_;%end;
%end;
%_start_:

/*************************************************************/
%let j = -1;
%do t = 1 %to %sysfunc(max(%scan(&times.,1),&lenghtOut.));
%let k=-1;
%do i = 1 %to &n.;
%let k=%eval(&k.+1);
%do e = 1 %to %scan(%superq(each),%eval(%sysfunc(mod(&k.,&ce.))+1),%str( ));
%let j = %eval(&j. + 1);
%if &j. %then&sep.;%scan(%superq(list),&i.,<{[( ,)]}>%str(;),Q)
%if 0<&lenghtOut. AND &lenghtOut.<&j. %then %return;
%end;
%end;
%end;
/*************************************************************/
%mend repList;


/*


options nosource;
%put %repList(('A,20' , "A.50", 'P!'), times = 5);
%put %repList(('A20', 'A50', 'P'), each = 5, sep=/);
%put %repList(('A20'; 'A50'; 'P'), times = 3, each = 2);
%put %repList(1 2 3, lenghtOut = 8, sep=q );
%put %repList(1 2 3, times = 3 2, each = 1,sep=%str(,));
%put %repList(1 2 3, times = 4, each = 2 3, lenghtOut = 13, sep=);

%put %repList(A B C, each=5, sep=_);
%put [%repList([C][B][A], times = 2, each = 2 3 5, lenghtOut = 14, sep=] [)];
%put >%repList([!][$][|], times = 4, each = 2 3, lenghtOut = 13, sep=< >)<;

%put %repList(T o l, each = 1 2, sep=);

%put %repList(# !, times=12, each = 3 2, lenghtOut=12*(3+2)-3, sep=);
%put %repList(/ $, times=12, lenghtOut=12, sep=);

%put @%repList()@;
%put @%repList(,times=12)@;
%put @%repList(,times=12,sep=#)@;
options source;


*/


/*** HELP START ***//*

### EXAMPLES AND USECASES: ####################################################

**EXAMPLE 1.** Simple repetition of all elements:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put %repList((A,B,C,D), times=3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 2.** Simple repetition of each element:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put %repList(("A",'B',"C",'D'), each=3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 3.** Simple repetition with a separator:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put %repList(A10;B20;C30, times=3, each=2, sep=Q);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 4.** Recycle elements up to 8 with a comma as a separator:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put %repList(1 2 3, lenghtOut=8, sep=c);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**EXAMPLE 5.** Separate number of repetitions for each element:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put [%repList([D][C][B][A], each = 2 3 5 7, sep=] [)];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**EXAMPLE 6.** "ASCII art" butterflies:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%put {>%repList(! $ |, times = 2, each =2 1, sep=<} ... {>)<};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 7.** Data repeating:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data A;
  x=17;
data B;
  x=42;
data C;
  x=303;
run;

data Times2_A10B11C12;
  set
    %repList(A B C, times = 2, each =10 11 12)
  ;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


---

*//*** HELP END ***/

/**###################################################################**/
/*                                                                     */
/*  Copyright Bartosz Jablonski, since 2023.                           */
/*                                                                     */
/*  Code is under the MIT license. If you want - you can use it.       */
/*  But it comes with absolutely no warranty whatsoever.               */
/*  If you cause any damage or something - it will be your own fault.  */
/*  You've been warned! You are using it on your own risk.             */
/*  However, if you decide to use it don't forget to mention author.   */
/*  Bartosz Jablonski (yabwon@gmail.com)                               */
/*                                                                     */
/**###################################################################**/
