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?

1

3 Answers 3

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} 
3
  • 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. Dec 30, 2012 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, 2012 at 6:19
  • 1
    "The Tex Book" by D.E. Knuth.
    – Ahmed Musa
    Jan 2, 2013 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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .