10

Given

\def\stuff{a,b,c}

I would like to be able to do

\foreach \x in {c,b,a} {...}

without inverting the list \stuff manually. For example is there some sort of \invert macro that would allow me to write

\foreach \x in \invert{\stuff} {...}
equaeghe
  • 5,976
  • 4
  • 30
  • 36

3 Answers3

11

A manual solution, where the reversed list is constructed in a first \foreach loop:

\documentclass{article}
\usepackage{pgffor}

\begin{document}

\let\mylist\empty
\foreach\x in {1,...,4} {
  \ifx\mylist\empty
    \xdef\mylist{\x}%
  \else
    \xdef\mylist{\x,\mylist}%
  \fi
}
\foreach\x in \mylist {
  [\x]
}

\end{document}

Result

Heiko Oberdiek
  • 271,626
8

You can use xparse to get a good way to feed \foreach with a control sequence holding the list and also to reverse it:

\documentclass{article}
\usepackage{pgffor,xparse}

\ExplSyntaxOn

\NewDocumentCommand{\Foreach}{ s m m m }
 {
  \IfBooleanTF{#1}
   {
    \equaeghe_reverseforeach:Non #2 { #3 } { #4 }
   }
   {
    \equaeghe_foreach:Non #2 { #3 } { #4 }
   }
 }
\cs_new_protected:Npn \equaeghe_foreach:Nnn #1 #2 #3
 {
  \foreach #1 in { #2 } { #3 }
 }
\cs_new_protected:Npn \equaeghe_reverseforeach:Nnn #1 #2 #3
 {
  \seq_set_split:Nnn \l__equaeghe_list_seq { , } { #2 }
  \seq_reverse:N \l__equaeghe_list_seq
  \tl_set:Nx \l__equaeghe_reverselist_tl
   { \seq_use:Nnnn \l__equaeghe_list_seq { , } { , } { , } }
  \equaeghe_foreach:NVn #1 \l__equaeghe_reverselist_tl { #3 }
 }
\cs_generate_variant:Nn \equaeghe_reverseforeach:Nnn { No }
\cs_generate_variant:Nn \equaeghe_foreach:Nnn { NV } 
\cs_generate_variant:Nn \equaeghe_foreach:Nnn { No }

\tl_new:N \l__equaeghe_reverselist_tl
\seq_new:N \l__equaeghe_list_seq

\ExplSyntaxOff


\begin{document}

\Foreach\x{a,b,c}{\x}

\Foreach*\x{a,b,c}{\x}

\Foreach\x{a,...,g}{\x}

\Foreach*\x{a,...,g}{\x}

\def\stuff{a,b,c}

\Foreach\x{\stuff}{\x}

\Foreach*\x{\stuff}{\x}

\end{document}

The *-version reverses the list.

enter image description here

egreg
  • 1,121,712
4

Here is another approach. I assume your list is a macro; it doesn't have to be. The \foreach loop gives you the transformed list

\mytranslist -> \do{4}\do{3}\do{2}\do{1}

You can then define \do to be any operator/processor that you wish. For example, to print the list, I define \do to yield the format [x].

\documentclass{article}
\usepackage{pgffor}
\begin{document}    
\def\mylist{1,...,4}
\def\do#1{%
  \xdef\mytranslist{\noexpand\do{#1}%
    \ifdefined\mytranslist\unexpanded\expandafter{\mytranslist}\fi
  }%
}
\let\mytranslist\undefined
\foreach \x in \mylist {\do{\x}}
% To print the list:
\def\do#1{[#1]}
\mytranslist
\end{document}

enter image description here

With the latest version of loops package, you need less estate:

\documentclass{article}
\usepackage{loops}[2012/10/10]
\begin{document}
\def\mylist{1,...,4}
\foreachfox [list is a macro, reverse list] \mylist {[#1]}
\end{document}
Ahmed Musa
  • 11,742
  • Where we can find loops.sty? Has it made to CTAN already? –  Oct 15 '12 at 00:19
  • I haven't seen it announced on comp.text.tex, the usual notice board used by CTAN. You may have to wait a few hours or days. – Ahmed Musa Oct 15 '12 at 00:23