[Tex/LaTex] Nested foreach inside a TikZ matrix for both rows and columns

tikz-pgf

I'm trying to create a matrix using nested \foreach loops. I tried following the example I found in a previous question, but I keep getting errors.

Here is the code I tried to run:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
  \foreach \i in {0,...,5} {
    \xappto\mymatrixcontent{\expandonce{
      \node {\i}; & 
    }}
  }
  \xappto\mymatrixcontent{\\}
}
\row{1}

\begin{tikzpicture}
  \matrix[matrix of nodes]{
    \mymatrixcontent
  };
\end{tikzpicture}
\end{document}

I'm getting an error:

! Undefined control sequence.
\\  ->\let \reserved@e 
                       \relax \let \reserved@f \relax \@ifstar {\let \reserv...
l.16 \row{1}

I noticed that this error occurs only after adding the new row after the \foreach loop. Is there a way to avoid it?

EDIT: I completed the example.

Best Answer

If you do

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \gappto\mymatrixcontent{\node{\i}; \&}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

(using \& is better because of problems with "naked" & tokens; percusse's answer tells how to cope with this when building the matrix) then \mymatrixcontent will expand to

\node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \&\

and the current definition of \i will be used, which is "print a dotless i", because \i will expand to the successive values only during the action of \foreach. So what's needed is the expansion of \i during the action of \foreach:

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \begingroup\edef\x{\endgroup
       \noexpand\gappto\noexpand\mymatrixcontent{\noexpand\node{\i}; \&}}\x
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

However one has to pay close attention when using \edef: not all tokens are allowed inside the replacement text and those which we want to get as themselves need to be prefixed by \noexpand. In this particular case, where \i is the only token to be expanded, a different method can be used

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \expandafter\gappto\expandafter\mymatrixcontent\expandafter{%
      \expandafter\node\expandafter{\i} \&}}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

because the \expandafter chain will cause the expansion of \i before \gappto is executed.


A different approach could be with expl3:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{matrix}

\ExplSyntaxOn
\NewDocumentCommand{\row}{mmm}
 {%#1 is the macro to define, #2 is the final number, #3 is the code
  \tl_clear_new:N #1
  \int_step_inline:nnnn { 0 } { 1 } { #2 }
   {
    \tl_put_right:Nn #1 { #3 }
   }
  \tl_put_right:Nn #1 { \\ }
 }
\ExplSyntaxOff

\begin{document}
\row{\mymatrixcontent}{5}{\node { #1 }; \& }

\begin{tikzpicture}
  \matrix[matrix of nodes,ampersand replacement=\&]{
    \mymatrixcontent
  };
\end{tikzpicture}
\end{document}

In the third argument to \row, #1 is successively evaluated as 0,...,5 (because 5 is the second argument).

enter image description here