# How do I use the ampersand (&) inside a foreach or conditional (or other group/environment) when building tables?

I am trying to build a table, and inside the tabularx environment I would like to have a loop, something like (here is a MWE):

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
\foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
\textbf{column1} & two & three & four & five
}
\end{tabularx}

\end{document}


This doesn't work, because the ampersands (&) are causing problems. If I escape the &s, then the entire line gets printed in the first column, along with the literal ampersands, kind of like:

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
\foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
\textbf{column1} \& two \& three \& four \& five
}
\end{tabularx}

\end{document}


This yields:

|column1 &      | | | |
| two & three & | | | |
| four & five   | | | |


Whereas what I want is:

|column 1 | two | three | four | five |
|column 1 | two | three | four | five |
|column 1 | two | three | four | five |


....

Any ideas on how I can achieve this? I'm actually NOT looking to make identical rows - the rows will be different. This is just a MWE. Thanks!

Edit: I have tried implementing Herbert's answer as recommended in the comments section. It results in no output - just a blank PDF. Here is how I implemented it:

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}

\resettabtoks
\foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
% \textbf{column1} \& two \& three \& four \& five
\addtabtoks{\textbf{column1} & two & three & four & five \\\hline}%
}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
\printtabtoks
\end{tabularx}

\end{document}


Any ideas on what I am doing wrong? Thanks!

-
Herbert's answer at tex.stackexchange.com/questions/7590/… is very much related. –  Steven B. Segletes Mar 12 '14 at 14:39
Welcome to TeX.SX! Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}. –  Christian Hupfer Mar 12 '14 at 14:59
Also you need \raggedright\arraybackslash in your preamble. –  Andrew Swann Mar 12 '14 at 16:43
You have to use \global\@tabtoks, because \foreach executes each cycle in a group. Related: tex.stackexchange.com/questions/62177/copy-table-row-n-times –  egreg Mar 12 '14 at 16:44
You are also missing \arraybackslash after \raggedright in the last column specification. –  egreg Mar 12 '14 at 16:51

Presumably you are doing this because you want the rows of the table to depend on the counter in the loop. In this case you will need a way to add expanded objects to the list of tokens. Here I add an \eaddtabtoks macro in addition to egreg's corrections to the global assignments.

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx,etoolbox}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}

\resettabtoks
\foreach \r in {1,...,\nRows}{
\addtabtoks{ & three & four & five \\}%
}

\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{2.2cm}*{4}{@{}>{\raggedright\arraybackslash}X}@{}}
\printtabtoks
\end{tabularx}%

\end{document}

-

You're missing the fact that \foreach executes each cycle in a group, so when finishing it the change to \@tabtoks is undone.

Add \global in the relevant places (and also \arraybackslash in the specification for the last column, but this is another problem).

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
%%% assignments to \@tabtoks must be global, because they are done in \foreach
%%% variable should always be operated on always locally or always globally
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}
\resettabtoks
\foreach \r in {1,...,\nRows}{
\addtabtoks{\textbf{column1} & two & three & four & five \\\hline}%
}
\noindent\begin{tabularx}{\textwidth}{
@{}>{\raggedright}p{2.2cm}
@{}>{\raggedright}X
@{}>{\raggedright}X
@{}>{\raggedright}X
@{}>{\raggedright\arraybackslash}X
@{}
}
\printtabtoks
\end{tabularx}

\end{document}

-
Thanks everyone! All responses were helpful. I have posted a related question here: [link]tex.stackexchange.com/questions/165208/… would be grateful for additional help. Cheers. –  Shafique Jamal Mar 12 '14 at 21:28

If your are open to using (here) another loop than \foreach then there are options, like \xintFor from package xinttools. The syntax is a bit different, and using \xintFor at this place does not exclude using \foreach at others...

Update adds a second method for people loving the bleeding edge.

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{xinttools}
\newcommand{\nRows}{5}
% \usepackage{tabu} % alternative to tabularx
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright\arraybackslash}X@{}}
\xintFor* #1 in {\xintSeq {1}{\nRows}}
\do
{(\textsl{row #1}) \textbf{column1} & two & three & four & five
\\ }
\end{tabularx}

% Note with a tabu environment of package tabu, \arraybackslash is not needed
% \begin{tabu} to \textwidth{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
%     \xintFor* #1 in {\xintSeq {1}{\nRows}}
%     \do
%     {(\textsl{row #1}) \textbf{column1} & two & three & four & five
%     \\ }
% \end{tabu}

\end{document}


Here is an idiosyncratic way which relies on an expandable loop (\xintFor is not expandable despite the fact it enjoys tabulars), and without counters! (\xintFor does not use counters either). \xintiloopindex can not be within braces; and in this example we need to hide the tabulations, for the \xintiloopindex mechanism to work, because non-expandable material is encountered before.

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{xinttools}
\newcommand{\nRows}{5}
\def\TAB{&}
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright\arraybackslash}X@{}}
\xintiloop [1+1]
(\bgroup\slshape row \xintiloopindex\egroup )% \xintiloopindex can not be
% within braces...
\textbf{column1} \TAB two \TAB three \TAB four \TAB five \\
\ifnum\nRows>\xintiloopindex\space
\repeat
\end{tabularx}

\end{document}

-