TikZ 矩阵中行和列的嵌套 foreach

TikZ 矩阵中行和列的嵌套 foreach

我正在尝试使用嵌套循环创建矩阵\foreach。我尝试按照我在上一个问题,但我一直收到错误。

这是我尝试运行的代码:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
  \foreach \i in {0,...,5} {
    \xappto\mymatrixcontent{\expandonce{
      \node {\i}; & 
    }}
  }
  \xappto\mymatrixcontent{\\}
}
\row{1}

\begin{tikzpicture}
  \matrix[matrix of nodes]{
    \mymatrixcontent
  };
\end{tikzpicture}
\end{document}

我收到一个错误:

! Undefined control sequence.
\\  ->\let \reserved@e 
                       \relax \let \reserved@f \relax \@ifstar {\let \reserv...
l.16 \row{1}

我注意到只有在循环后添加新行后才会出现此错误\foreach。 有办法避免吗?

编辑:我完成了这个例子。

答案1

如果你

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \gappto\mymatrixcontent{\node{\i}; \&}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

\&由于“裸”&标记的问题,使用更好; percusse 的答案告诉了在构建矩阵时如何应对这个问题)然后\mymatrixcontent将扩展为

\node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \&\

并且将使用 的当前定义\i,即“打印无点 i”,因为\i仅在 操作期间才会扩展为连续值。因此,需要的是在 操作期间\foreach扩展:\i\foreach

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \begingroup\edef\x{\endgroup
       \noexpand\gappto\noexpand\mymatrixcontent{\noexpand\node{\i}; \&}}\x
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

然而,使用时必须特别注意\edef:并非所有标记都允许放在替换文本中,而我们想要作为其本身获取的标记需要以 为前缀\noexpand。在这种特殊情况下,其中\i是唯一需要扩展的标记,可以使用不同的方法

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \expandafter\gappto\expandafter\mymatrixcontent\expandafter{%
      \expandafter\node\expandafter{\i} \&}}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

因为该链在执行之前\expandafter会引起扩展。\i\gappto


另一种方法可能是expl3

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{matrix}

\ExplSyntaxOn
\NewDocumentCommand{\row}{mmm}
 {%#1 is the macro to define, #2 is the final number, #3 is the code
  \tl_clear_new:N #1
  \int_step_inline:nnnn { 0 } { 1 } { #2 }
   {
    \tl_put_right:Nn #1 { #3 }
   }
  \tl_put_right:Nn #1 { \\ }
 }
\ExplSyntaxOff

\begin{document}
\row{\mymatrixcontent}{5}{\node { #1 }; \& }

\begin{tikzpicture}
  \matrix[matrix of nodes,ampersand replacement=\&]{
    \mymatrixcontent
  };
\end{tikzpicture}
\end{document}

在 的第三个参数中\row#1依次求值为 0,...,5(因为 5 是第二个参数)。

在此处输入图片描述

答案2

正如 Martin 在链接的答案中所写,它与\gappto命令一起工作。这是一个对我有用的例子。我还更改了 & 符号,因为将一个孤独的符号放入&扩展宏的内部总是有问题的 :)

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
  \foreach \i in {0,...,5} {
    \gappto\mymatrixcontent{\expandonce{
     A  \& 
    }}
  }
  \gappto\mymatrixcontent{\\}
}
\row{1}

\begin{tikzpicture}
  \matrix (a) [matrix of nodes,ampersand replacement=\&]{
    \mymatrixcontent
  };
    \draw (a-1-1) -- (a-1-5);
\end{tikzpicture}

\end{document}

代码输出

答案3

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{etoolbox}

\begin{document}
\begin{tikzpicture}
\let\mymatrixcontent\empty
\foreach \row in {1,...,8}{%%
\foreach \col in {1,...,5}{%
\xappto\mymatrixcontent{r\row c\col \expandonce{\&}}
}%
\gappto\mymatrixcontent{\\}
}%%

\matrix[matrix of nodes, ampersand replacement=\&,
column sep=2ex,  label={Matrix}
] (m){
\mymatrixcontent 
};
\end{tikzpicture}
\end{document}

答案4

没有扩展,没有全局分配,没有额外的包,没有额外的列,没有&符号快捷方式,只有两个\foreach循环。

但是,库|…|的语法matrix不再包含。但是,当您生成单元格时,您可以直接使用\node[…]{…};(或使用各种row …//样式来更改行、列或单元格的样式)column …row … column …

对于您来说,只需使用create matrix={1}{1, ..., 5}set matrix macro=#2。这将创建1包含 5 列12、... 的行,5但只将列号放在节点中。

代码

\documentclass[tikz]{standalone}
\tikzset{
  % \protected because \pgfmatrixnextcell and \pgfmatrixendrow expand
  % → can't use |…| shortcut, though
  matrix node/.style 2 args={
    name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn,
    alias={\tikzmatrixname'-#1-#2}},
  set matrix macro/.code=
    \protected\def\tikzmatrixcell##1##2{\node[matrix node={##1}{##2}]{#1};},
  set matrix macro'/.code=\protected\def\tikzmatrixcell##1##2{#1},
  set matrix macro=r#1\,c#2,
  create matrix/.style 2 args={
    /tikz/matrix/content/.initial=,
    /tikz/matrix/create rows/.style={
      /tikz/matrix/reset create cell,
      /tikz/matrix/create columns/.style={
        /tikz/matrix/create cell={##1}{####1}},
      /tikz/matrix/create columns/.list={#2},
      /tikz/matrix/content/.append=\pgfmatrixendrow},
    /tikz/matrix/create rows/.list={#1},
    /tikz/node contents=\pgfkeysvalueof{/tikz/matrix/content}},
  matrix/reset create cell/.style={
    /tikz/matrix/create cell/.style 2 args={
      /tikz/matrix/content/.append=\tikzmatrixcell{##1}{##2},
      /tikz/matrix/create cell/.style 2 args={
        /tikz/matrix/content/.append=
          \pgfmatrixnextcell\tikzmatrixcell{####1}{####2}}}}}
\begin{document}
\tikz
\matrix[
  draw, column sep=2ex,
  set matrix macro=#2, create matrix={1}{1, ..., 5}];

\tikz
\matrix (m) [
  draw, column sep=2ex, row sep=1em,
  row 1 column 1/.style={set matrix macro=},
  column 1/.append style={set matrix macro=row    ##1},
  row    1/.append style={set matrix macro=column ##2},
  set matrix macro=#2#1, % like a spreadsheet
  create matrix={0, ..., 8}{0, A, B, ..., E}]
  (m'-1-A) edge[out=0, in=180] (m'-4-B);
\end{document}

输出

在此处输入图片描述

在此处输入图片描述

相关内容