# How can I get these two nested \foreach loops to work?

I try to use nested \foreach loops to create edges between many nodes.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {%
b/d,%
{a/b,c,d}%
} {
\typeout{\from-\targets}
\foreach \to in {\targets} {
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}
\end{document}


But this fails with the cryptic error

b-d
b-d
a-b,c,d
a-b,c,d

! Package PGF Math Error: Unknown function b' (in 'b').


As \typeout visible before the error show, seemingly \targets is not expanded and thus interpreted a single parameter instead of a list. Can expansion be forced at this point? Or is there another way to fix it?

-
Since you have some responses below that seem to answer your question, please consider marking one of them as ‘Accepted’ by clicking on the tickmark below their vote count (see How do you accept an answer?). This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). It's part of this site's idea to identify good questions and answers through upvotes and acceptance of answers. –  Jubobs Dec 10 '13 at 10:04

You need to remove the parentheses from the inner loop. Namely, instead of passing {\targets} to the \foreach loop, you should be passing \targets.

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

\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {%
b/d,%
{a/b,c,d}%
} {
\typeout{\from-\targets}
\foreach \to in \targets {
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}

\end{document}


-
Or \foreach \from/\targets in {b/{d},a/{b,c,d}}... –  Jubobs Dec 8 '13 at 18:13
@Jubobs which--what you suggest--is much easier to read and understand. :) I was just trying to stick with the OP's notation. –  A.Ellett Dec 8 '13 at 18:14
I couldn't make sense of the OP's notation, so I took some liberties :) –  Jubobs Dec 8 '13 at 18:16

Problems with \foreach aside, I think the syntax

\path (b) edge (d)
(a) edge (b) edge (c) edge (d);


comes much more natural. It is also much easier to change edge options on an edge-to-edge basis (or for more than one edge, too):

\path (b) edge (d) {[thick]
(a) edge (b) edge[green] (c) edge[red,->] (d)};


Though, a similar thing can still be done with \foreach, say

\path (b) edge (d) {[thick]
(a) \foreach \opt/\p in {/b, green/c, {red,->}/d}
{edge[style/.expand once=\opt] (\p)}};


With my qrr.misc library (code similar to the keys in another answer of mine), one can do

\path (b) edge (d) {[thick]
(a) [edges to={b,[green] c, [{red,->}] d}]};


It should be noted that the , in the options has to be protected somehow, either in that way shown or by doing {[red, ->] d}, i.e. enclosing the whole thing in braces. (This could be made more robust or can be changed to use ( and ) around the coordinates instead of using ,, but the implementation will need more parsing then.)

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{qrr.misc}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};  \node (b) at (0, -1) {};
\node (c) at (1, 0) {};  \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) edge (b) edge[green] (c) edge[red,->] (d)};
\end{tikzpicture}
\begin{tikzpicture}
\node (a) at (0, 1) {};  \node (b) at (0, -1) {};
\node (c) at (1, 0) {};  \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) \foreach \opt/\p in {/b, green/c, {red,->}/d}
{edge[style/.expand once=\opt] (\p)}};
\end{tikzpicture}
\begin{tikzpicture}
\node (a) at (0, 1) {};  \node (b) at (0, -1) {};
\node (c) at (1, 0) {};  \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) [edges to={b,[green] c, [{red,->}] d}]};
\end{tikzpicture}
\end{document}


## Output

-

The important thing is to be consistent in the way you specify elements in a list to be processed by \foreach.

In the approach below, which I find more intuitive, \targets gets expanded to {b} at the first iteration of the outer loop, and to {b,c,d} at the second one. Therefore, specifying \foreach \to in \targets for the inner loop works as expected.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {b/{d},a/{b,c,d}}
{%
\typeout{\from-\targets}
\foreach \to in \targets
{%
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}
\end{document}
`
-