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

2
  • 1
    This solution would help you: 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, 2017 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, 2017 at 14:22

2 Answers 2

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

2
  • 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, 2017 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). Jul 14, 2017 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.

You must log in to answer this question.

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