使用循环为另一个(foreach)循环生成列表

使用循环为另一个(foreach)循环生成列表

是否可以使用循环为 foreach 循环生成列表?更具体地说,我想要以下内容:

考虑一下我之前提出的一个问题的以下答案:https://tex.stackexchange.com/a/38793/4011

它工作得很好,除非我定义\alist如下:

\def\alist{
    \foreach \i in {1,2,3}{
      \i/1,
      }4/1
    }

我收到以下错误:

ERROR: Undefined control sequence.

--- TeX said ---
\foreach ...reach \let \pgffor@assign@before@code 
                                                  =\pgfutil@empty \let \pgff...
l.38   \rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}

有没有什么办法解决这一问题?

编辑

完整示例:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
  \def\rectDiv#1#2#3#4#5{%#columns, #rows, rectangle start, rectangle end, list of elements to fill
    \begin{tikzpicture}
      \draw #3 rectangle #4;
      \path #3;
      \pgfgetlastxy{\firstx}{\firsty}
      \path #4;
      \pgfgetlastxy{\secondx}{\secondy}
      \pgfmathsetlengthmacro{\xdiff}{\secondx-\firstx}
      \pgfmathsetlengthmacro{\ydiff}{\secondy-\firsty}
      \pgfmathsetlengthmacro{\myxstep}{\xdiff/#1}
      \pgfmathsetlengthmacro{\myystep}{\ydiff/#2}
      \foreach \x in {1,...,#1}{
        \draw ($#3 +\x*(\myxstep,0)$) -- ($#3 +(0,\ydiff) +\x*(\myxstep,0)$);
      }
      \foreach \y in {1,...,#2}{
        \draw ($#3 +\y*(0,\myystep)$) -- ($#3 +(\xdiff,0) +\y*(0,\myystep)$);
      }
      \edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}
      \temp{
        \path[fill=blue!20,draw] ($#3 + (\i*\myxstep,\j*\myystep)$) rectangle ($#3 + (\i*\myxstep,\j*\myystep) + (\myxstep,\myystep)$);
      }
    \end{tikzpicture}
  }
\begin{document}
  \rectDiv{7}{5}{(1,1)}{(4,3)}{0/0,1/1,2/0,5/3}

  \def\list{1/0}
  \rectDiv{7}{5}{(1,1)}{(4,3)}{\list}

  \rectDiv{7}{5}{(1,1)}{(4,3)}{\list,2/0,5/3}

  \def\alist{
    \foreach \i in {1,2,3}{
      \i/1,
      }4/1
    }

   \alist

   \rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}  %this doesn't  work

\end{document}

答案1

你的问题是你写的

\edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}

% Here is what #5 is in \temp:
\def\alist{
\foreach \i in {1,2,3}{
  \i/1,
  }4/1
}

这要求括号中的内容“完全可扩展”。可惜的是,\foreach是不可扩展的,它是 的一部分\alist。因此,当\temp被定义时,它会“尽可能地”扩展,并触及 代码中某些不可扩展的部分\foreach,在本例中是\let \pgffor@assign@before@code = ...\let是一个任务,并且不可扩展,因此不会被 改变\edef。因此,实际上并没有执行赋值,而是\edef继续尝试\pgffor@assign@before@code直接解释以下控制序列。毫不奇怪,它没有定义,因为应该是\let来定义它,所以你会得到一个错误。

为此,您必须创建一个包含输出\alist。例如,

\gdef\alist{}
\foreach \i in {1,2,3} {
 \xdef\alist{\alist \i/1,}
}
\xdef\alist{\alist 4/1}

然后您可以\alist直接使用而不是\temp.(我已经使用全局分配,因为\alist\foreach组中执行其内容。)

相关内容