tikz foreach 变量名称中的索引

tikz foreach 变量名称中的索引

我想要一组保存数值的变量(例如,cnt1、cnt2、cnt3)并根据 foreach 索引访问它们。

例如:

\foreach \i in {1,...,5} {
    \pgfmathtruncatemacro{\cnt\i}{\cnt\i + 4}
}

那可能吗?

(为清晰起见已编辑)

因为它仍然不是很清楚:我想要一个基于 foreach 索引构造的名称的变量的数值,并且我想在这个变量中执行数值运算(例如,使用 pgfmath* 命令)。

答案1

我认为您正在寻找的是列表结构。这是 tikz 中列表的一个示例。请注意列表定义中的双括号。此外,与大多数编程语言一样,列表位置索引从 0 开始。您可以在 tikz 文档的数学表达式语法部分中找到有关列表的更多信息。

\documentclass{minimal}

\usepackage{tikz}
\begin{document}

\begin{tikzpicture}

\def\numbers{{1,3,5,2,4}}

\foreach \i in  {0,...,4}{
    \pgfmathsetmacro{\n}{\numbers[\i] + 4}
    \draw[] (\i,0) -- (\i,\n);
}
    
\end{tikzpicture}

\end{document}

答案2

不确定我是否正确理解了你的意思,但是你可以使用循环选项访问循环的索引count=\macro例如

\documentclass{article}
\usepackage{tikz}
\begin{document}
\noindent\foreach [count=\i] \x in {2,3,4,5,6} {%
   cnt-\i = \x \\
  }
\end{document}

在此处输入图片描述

我不知道如何使用 来做(我认为)你想要做的事情pgffor。使用 Lua 来做类似的事情相当容易,但这当然需要使用 进行编译lualatex。我在下面添加了一个示例,其中值从循环保存到 Lua 表中,并且该\getcnt命令允许您根据索引从该表中打印一个值。

这是我的另一个愚蠢的 Lua 小示例,它可能完全浪费你的时间。使用以下命令进行编译lualatex

\documentclass{article}
\usepackage{luacode}
\newcommand{\getcnt}[1]{%
\luaexec{
tex.sprint(cnt[#1])
}}

\begin{document}
\begin{luacode}
cnt = {}
for i=1,10 do
  cnt[i] = i^2 + 4
end
\end{luacode}
\getcnt{2} \getcnt{5}
\end{document}

答案3

正如评论中提到的,如果您想要带有数字的变量名称,请参阅定义包含数字的命令/缩写

这是一种使用带有字母前缀的变量名执行所需操作的方法。您必须使用\csname cnt\i\endcsname来访问变量。

由于foreach循环是分组执行的,所以如果你想要内\global的效果在 之后可用,则必须使用。查看第一次循环和第二次循环后的区别。\defforeach\foreach

在此处输入图片描述 在此处输入图片描述

\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}

\newcommand{\cntA}{1}
\newcommand{\cntB}{2}
\newcommand{\cntC}{3}
\newcommand{\cntD}{4}
\newcommand{\cntE}{5}


\begin{document}
\foreach \i in {A, B, ..., E} {
    \pgfmathtruncatemacro{\temp}{\csname cnt\i\endcsname + 4}
    \edef\csname cnt\i\endcsname{\temp}
}

\noindent
After 1st loop:\par
cntA = \cntA\par
cntB = \cntB\par
cntC = \cntC\par
cntD = \cntD\par
cntE = \cntE\par

\foreach \i in {A, B, ..., E} {
    \pgfmathtruncatemacro{\temp}{\csname cnt\i\endcsname + 4}
    \expandafter\global\expandafter\edef\csname cnt\i\endcsname{\temp}
}

\medskip
\noindent
After 2nd loop:\par
cntA = \cntA\par
cntB = \cntB\par
cntC = \cntC\par
cntD = \cntD\par
cntE = \cntE\par
\end{document}

答案4

如果你真的想根据变量的值构造一个宏名\i,那么你需要使用构造\csname cnt\i\endcsname,其结果就是这样的宏。使用起来有点尴尬,所以像这样使用它:

\expandafter\let\expandafter\thiscnt\csname cnt\i\endcsname
% Use \thiscnt for things...

这也相当尴尬,但至少你只需要写一次,并且(更重要的是)不用担心在哪里\expandafter使用它。

(如果你是 TeX 编程新手:\expandafter使宏下一个在处理之前展开。您需要在中设置它\let,以便在\let实际运行时,它看到\thiscnt要设置为结果\csname...而不是其\csname本身。您需要两个\expandafters,因为您要跳过两个步骤。)

这不是列出清单的最佳方法;Frédéric 的答案要简单得多。

相关内容