15

I am trying to make a "for loop" that will iterate the variable reaches 1. However, none of the "for loops" I have found in the Internet works.

These files will be distributed to other people and thus it would help if we only stick to the default packages. In this case, I'm using the ifthen package.

\newcommand{\displayauthors}[1]
{
\newcounter{blargh}
\setcounter{blargh}{#1}
\ifthenelse{#1 = 0}{

}{
\the\value{blargh}
\displayauthors{\value{blargh}}
}

This command is error-free. However, when I run

\displayauthors{2}

LaTeX complains that

Command \c@blargh already defined.

What is causing this and how do I fix this?

22

The following solution doesn't need any package nor any counter, is much faster, resolves tail recursion, is expandable, and deals with the trailing/last comma (,).

\documentclass{article}
\def\displayauthors#1{%
  \ifnum#1>0 #1\ifnum\numexpr#1-1>0, \fi
    \expandafter\displayauthors\expandafter{\number\numexpr#1-1\expandafter}%
  \fi
}
\begin{document}
\displayauthors{10}

\edef\x{\displayauthors{10}}\x
\end{document} 
  • 2
    +1 that's what I'd do, but I thought I'd keep my answer closer to the MWE to show what was wrong with the original code, rather than just replace all of it. Good to show this alternative though. – David Carlisle Dec 30 '12 at 3:37
  • Hey thanks. That seems to work. May I know the logic behind this? I don't know what \displayauthors#1 does, among other things. Does anyone have a good source I can read? – Guissmo Dec 31 '12 at 6:19
  • 1
    "The Tex Book" by D.E. Knuth. – Ahmed Musa Jan 2 '13 at 17:03
16

Move

\newcounter{blargh}

out of the macro body and place it before the definition. You do not want to allocate a new register on each use, each loop should use the same register which is allocated once at the start.


Also you need to decrement the counter and a few % at ends of lines

enter image description here

\documentclass{article}
\usepackage{ifthen}
\newcounter{blargh}

\newcommand{\displayauthors}[1]
{%
\setcounter{blargh}{#1}%
\ifthenelse{#1 = 0}{%
}{%
\theblargh, %
\addtocounter{blargh}{-1}%
\displayauthors{\value{blargh}}%
}}

\begin{document}

\displayauthors{10}

\end{document}
8

You mention not finding any success with a for loop. Here's one option:

enter image description here

\documentclass{article}
\usepackage{multido}% http://ctan.org/pkg/multido
\newcommand{\displaynums}[1]{%
  \ifnum#1<0\else\multido{\i=#1+-1}{#1}{\i\ }\unskip\fi}
\begin{document}
4: \displaynums{4}\par
12: \displaynums{12}\par
1: \displaynums{1}\par
0: \displaynums{0}\par
-7: \displaynums{-7}
\end{document}

multido provides an iterative/sequential interface to variables:

\multido{<var>=<start>+<increment>}{<times>}{<stuff>}

There is some difference between real/integer usage. See the multido documentation for more information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.