1

I have a list of lists, and I'm using nested \foreach loops to iterate through them. By using [count=\var], I'm able to use \var to access the length of the outer loop (after I've iterated through). However, I am not able to use this method to access the length of the inner loops. In my case, all the inner loops should have the same length, but technically I wanted to access the length of the last of the inner loops. Here's what I have so far:

\documentclass{article}
\usepackage{tikz}
\begin{document}

% The first two work:

\begin{tikzpicture}
  \foreach \from [count=\to] in {2,3,1} {
    \draw (\from,1) -- (\to,2);
  }
  \draw[gray] (0.5,0.5) rectangle (\to+0.5,2.5);
\end{tikzpicture}

\begin{tikzpicture}
  \foreach \from [count=\to] in {1,3,2} {
    \draw (\from,1) -- (\to,2);
  }
  \draw[gray] (0.5,0.5) rectangle (\to+0.5,2.5);
\end{tikzpicture}

% This one does not work:

\begin{tikzpicture}
  \foreach \list [count=\row] in {{2,3,1},{1,3,2}} {
    \foreach \from [count=\to] in \list {
      \draw (\from,\row) -- (\to,\row+1);
    }
  }
  \draw[gray] (0.5,0.5) rectangle (\to+0.5,\row+1.5);
\end{tikzpicture}

\end{document}

Here's what I want to end up with:

desired result

Pi Fisher
  • 559
  • 3
  • 11
  • 1
    This solution would help you: https://tex.stackexchange.com/a/115428/124842 (as workaround). So 1. in preamble: \newcommand*{\LastLoopValue}{0}, 2. in second for loop \xdef\LastLoopValue{\to} and finaly 3. \draw[gray] (0.5,0.5) rectangle (0.5+\LastLoopValue,\row+1.5); instead of \draw[gray] (0.5,0.5) rectangle (\to+0.5,\row+1.5); – Bobyandbob Jul 13 '17 at 19:56
  • Thanks, this definitely works as a workaround. Unfortunately, I really dislike using global variables (which LaTeX really wants me to use), so I'm going to keep looking for alternatives. – Pi Fisher Jul 14 '17 at 14:22

2 Answers2

1

This uses LaTeX counters in combination with TikZ macros. All counter operations are global.

\documentclass{article}
\usepackage{tikz}

\newcounter{to}
\newcounter{row}

\begin{document}


\begin{tikzpicture}
  \setcounter{to}{0}
  \foreach \from in {2,3,1} {
    \stepcounter{to}
    \draw (\from,1) -- ({\theto},2);
  }
  \draw[gray] (0.5,0.5) rectangle (\theto+0.5,2.5);
\end{tikzpicture}

\begin{tikzpicture}
  \setcounter{to}{0}
  \foreach \from in {1,3,2} {
    \stepcounter{to}
    \draw (\from,1) -- (\theto,2);
  }
  \draw[gray] (0.5,0.5) rectangle (\theto+0.5,2.5);
\end{tikzpicture}


\begin{tikzpicture}
  \setcounter{row}{0}
  \foreach \list in {{2,3,1},{1,3,2}} {
    \stepcounter{row}
    \setcounter{to}{0}
    \foreach \from in \list {
      \stepcounter{to}
      \draw (\from,\therow) -- (\theto,\therow+1);
    }
  }
  \draw[gray] (0.5,0.5) rectangle (\theto+0.5,\therow+1.5);
\end{tikzpicture}

\end{document}

demo

Bobyandbob
  • 4,899
John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • Thanks! This works for this case, but I'm averse to using global variables (even though LaTeX really likes them). I found another solution that has a downside of needing to iterate through the outer loop twice (and the final inner loop once). – Pi Fisher Jul 14 '17 at 14:24
  • 1
    Only global variables can get out of a \foreach step. Presumably [count=\var] translates as \let\var=\pgf@count, or some sort of global variable used by tikz for all loops (hence the problem with nested loops). – John Kormylo Jul 14 '17 at 18:24
0

This solution has the disadvantage of needing to iterate through the list multiple times, but it avoids setting a global variable.

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
  \foreach \list [count=\row] in {{2,3,1},{1,3,2}} {
    \foreach \from [count=\to] in \list {
      \draw (\from,\row) -- (\to,\row+1);
    }
  }
  \foreach \list [count=\count] in {{2,3,1},{1,3,2}} {
    \ifx \count \row
      \foreach \from [count=\to] in \list {
      }
      \draw[gray] (0.5,0.5) rectangle (\to+0.5,\row+1.5);
    \fi
  }
\end{tikzpicture}

\end{document}

The issue with my first version is that \to was out-of-scope when I was trying to use it. This uses it when it's still in scope.

Pi Fisher
  • 559
  • 3
  • 11