8

I want to have a set of variables holding numerical values (e.g., cnt1, cnt2, cnt3) and access them based on the foreach index.

For example:

\foreach \i in {1,...,5} {
    \pgfmathtruncatemacro{\cnt\i}{\cnt\i + 4}
}

Is that possible?

(edited for clarity)

Since it is not still very clear: I want to have a numerical value to a variable with a name that is constructed based on the foreach index, and I want to do numerical operations in this variable (e.g., using pgfmath* commands).

user10097
  • 183
  • 1
    Welcome to TeX.SX! Would you please be more specific on your intentions? – egreg Dec 16 '11 at 17:19
  • 1
    Regarding macro names with numbers: http://tex.stackexchange.com/questions/9718/definining-commands-abbreviations-that-contain-numbers – Torbjørn T. Dec 17 '11 at 13:05

4 Answers4

8

Not sure I understand you correctly, but you can access the index of the loop with the count=\macro option to the loop, e.g.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\noindent\foreach [count=\i] \x in {2,3,4,5,6} {%
   cnt-\i = \x \\
  }
\end{document}

enter image description here

I have no idea how to do what (I think) you're after with pgffor. It is fairly easy to something kind of similar with Lua, but that requires of course compiling with lualatex. I added an example below, where values are saved to a Lua table from a loop, and the \getcnt command allows you to print a value from that table based on the index.

So another of my silly little Lua-examples, which may or may not be a complete waste of your time. Compile with lualatex:

\documentclass{article}
\usepackage{luacode}
\newcommand{\getcnt}[1]{%
\luaexec{
tex.sprint(cnt[#1])
}}

\begin{document}
\begin{luacode}
cnt = {}
for i=1,10 do
  cnt[i] = i^2 + 4
end
\end{luacode}
\getcnt{2} \getcnt{5}
\end{document}
Torbjørn T.
  • 206,688
8

I think what you are looking for is a list structure. Here is an example of a list in tikz. Note the double braces in the list definition. In addition, the list position index starts at 0, as with most programming languages. You can find a little more on lists in the tikz documentation in the section on syntax for math expressions.

\documentclass{minimal}

\usepackage{tikz} \begin{document}

\begin{tikzpicture}

\def\numbers{{1,3,5,2,4}}

\foreach \i in {0,...,4}{ \pgfmathsetmacro{\n}{\numbers[\i] + 4} \draw[] (\i,0) -- (\i,\n); }

\end{tikzpicture}

\end{document}

dexteritas
  • 9,161
Frédéric
  • 11,087
  • 3
  • 37
  • 43
4

As mentioned in the comments if you want variable names with numbers refer to Defining commands/abbreviations that contain numbers.

Here is a way to do what you want with variable names that have an alphabetic prefix. You have to use \csname cnt\i\endcsname to access the variable.

Since the foreach loop is executed in a group, you have to use \global if you want the effect of the \def within the foreach to be available after the \foreach. See the difference after the first loop and the second loop.

enter image description here enter image description here

\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}

\newcommand{\cntA}{1}
\newcommand{\cntB}{2}
\newcommand{\cntC}{3}
\newcommand{\cntD}{4}
\newcommand{\cntE}{5}


\begin{document}
\foreach \i in {A, B, ..., E} {
    \pgfmathtruncatemacro{\temp}{\csname cnt\i\endcsname + 4}
    \edef\csname cnt\i\endcsname{\temp}
}

\noindent
After 1st loop:\par
cntA = \cntA\par
cntB = \cntB\par
cntC = \cntC\par
cntD = \cntD\par
cntE = \cntE\par

\foreach \i in {A, B, ..., E} {
    \pgfmathtruncatemacro{\temp}{\csname cnt\i\endcsname + 4}
    \expandafter\global\expandafter\edef\csname cnt\i\endcsname{\temp}
}

\medskip
\noindent
After 2nd loop:\par
cntA = \cntA\par
cntB = \cntB\par
cntC = \cntC\par
cntD = \cntD\par
cntE = \cntE\par
\end{document}
Peter Grill
  • 223,288
3

If you literally want to construct a macro name based on the value of the variable \i, you want to use the construction \csname cnt\i\endcsname, the result of which is exactly such a macro. It's a little awkward to use, so use it like this:

\expandafter\let\expandafter\thiscnt\csname cnt\i\endcsname
% Use \thiscnt for things...

This is also pretty awkward, but at least you only have to write it once and (more importantly) not worry about where you need \expandafter when you do use it.

(If you are new to TeX programming: \expandafter makes the macro after the next one expand before processing. You need it in the \let so that, when \let actually runs, it sees that \thiscnt is to be set to the result of \csname..., rather than \csname itself. You need two \expandafters because you're skipping two steps forward.)

This is not the best way to do a list; Frédéric's answer is much easier.

Ryan Reich
  • 37,958