How can I iterate, loop, process, or otherwise do something, with each element from a comma separated list of things?
This question has been asked perhaps many many times, and the are already lots of very good answers everywhere. However I think it would also be valuable to have a single reference point where all such alternative techniques are explained in detail, with their advantages and disadvantages discussed.
All of plain-TeX, LaTeX, LaTeX3, LuaTeX, Context, etoolbox, pgffor, etc. answers are invited. Please consider explaining, for example:
- How does the command/method deal with whitespace around items?
- How does the command/method deal with empty/missing items? (e.g.
a,b,,c
) - How does the command/method deal with a trailing comma?
- Can the command/method work of a list stored on a macro?
- Is each iteration evaluated globally or on a local group? (i.e., if a command is defined during an iteration, does the command survive the loop?)
- Do items get expanded or somehow mangled before being processed?
- What about lists where items are
key=value
or some other kind of pairs? - Does the method work for lists separated with something other than a comma?
- Any other thing I should know before deciding to use this method?
Best Answer
The main loop for comma separated lists in LaTeX3 is
The first argument is an explicit list, the second argument tells LaTeX what to do with each item. For instance, we want to print an
enumerate
environment from the items:I used
\fbox
in order to illustrate some of the features:spaces are stripped on either side of the items;
empty items are ignored (empty means only spaces between commas);
no expansion is performed on the item.
Note that the current item is denoted by
#1
and it's literally available, which is not the case with the usual\@for
, where the current item is hidden in a macro. In the code above we have to use double##1
because we're inside a macro definition.A similar function is
\clist_map_function:nN
, which has the advantage of being fully expandable (but only inx
full expansion, notf
). The above example would beIn this case the current item is passed as an argument to the indicated function.
List mappings can be broken; let's say, in the above example, we want to stop processing if an item is
\stop
:Note that complex code shouldn't be used in
\NewDocumentCommand
, so I defined an auxiliary function for this purpose.One can also use
and the argument given to this function will be executed before breaking the mapping.
The same features apply when using
for evaluating a set of key-value pairs: leading and trailing spaces are ignored as are empty (blank) items.
If the comma separated list is stored in a macro, one can use
with the same ideas. In my opinion, it's bad programming style allowing both inputs and a variant should be defined.
Setting a variable with the contents of the macro holding the comma separated list is done because this process “normalizes” the comma separated list for better usage in
\clist_map_inline:Nn
.If other delimiters are desired, the better method is to go to sequences; use
\seq_map_inline:Nn
or\seq_map_function:NN
after splitting the input into components withFull example:
Also here the splitting ignores leading and trailing spaces and also empty items.