请参阅以下 MWE 以更好地理解我的意思。
\documentclass[preview,border=12pt]{standalone}
\usepackage{pgffor,multido}
\begin{document}
\section*{foreach}
\foreach \ix in {0,1,...,3}{%
\foreach \iy in {0,1,...,\ix}{(\ix,\iy)\ }\endgraf}
\section*{multido}
\multido{\ix=0+1}{4}{%
\multido{\iy=0+1}{\the\numexpr\ix+1\relax}{(\ix,\iy)\ }\endgraf}
\end{document}
为何无法\foreach \x in {0,1,...,0}{}
进行第二次迭代?
答案1
该\foreach
命令有其怪癖;但是,您的 MWE 中显示的行为与第 56 节一致PGF 手册 (2.10),详细描述了...
内部所起的作用\foreach
。
考虑\foreach \xx in {x,y,...,z}
。差值 d= y
-x
用于“填充”由...
(参见第 505 页) 隐式指定的元素:
在这种情况下,列表阅读的部分
x,y,...,z
被替换为x, x + d, x + 2d, x + 3d,
...x + md
,其中最后的点是语义点,而不是句法点。值 m 是最大数字,使得如果 d 为正,则x
+ md ≤ ,或者如果 d 为负,则+ md ≥ 。z
x
z
可能违反直觉的是,前两次迭代(使用x
和y
)将执行无论 的值z
是什么。
解决问题的一种方法是删除元素y
,如 PGF 手册(同上)所述:
如果
...
在列表中的第一个项目之后立即使用,即如果存在x
但没有y
,则差异d显然无法计算,并且1
如果点后面的数字z
大于,则设置为,如果小于,则x
设置为。−1
z
\foreach \iy in {0,...,0}
,当\ix
具有值时出现,仅根据需要对0
进行迭代。0
\documentclass[preview,border=12pt]{standalone}
\usepackage{pgffor,multido}
\begin{document}
\section*{foreach}
\foreach \ix in {0,1,...,3}{%
\foreach \iy in {0,...,\ix}{(\ix,\iy)\ }\endgraf} % omit 1 here
\section*{multido}
\multido{\ix=0+1}{4}{%
\multido{\iy=0+1}{\the\numexpr\ix+1\relax}{(\ix,\iy)\ }\endgraf}
\end{document}
编辑: 据观察@Sigur,上述修复仅在增量等于 1 时才有效,就像 OP 示例中的情况一样。\foreach
在增量不为 1 的情况下,需要进行更实质性的修改才能相应地改变 的行为。比如说,如果你想让它的\foreach \xx {x,y,...,z}
行为更像 Matlabfor
循环,
for i=x:y-x:z
% for-loop body
end
您必须考虑 9 种不同的情况,具体取决于 、 和 相互之间的比较方式x
(y
< z
、= 或 >):
x
<y
<z
:列表无变化;x
<y
=z
:列表应该是x,y
;x
<y
>z
:列表应该为空;x
=y
<z
:这会引发TeX capacity exceeded
错误;x
=y
<z
:这会引发TeX capacity exceeded
错误;x
=y
<z
:这会引发TeX capacity exceeded
错误;x
>y
<z
:列表应该为空;x
>y
=z
:列表应该是x,y
;x
>>y
:z
列表无变化;
您可以在进入循环之前比较x
、y
和,然后根据您所处的 9 种情况中的哪一种,以编程方式生成要在中使用的相应列表。但是,我觉得这种方法超出了 OP 问题的范围,可能值得在其他地方得到适当的答案......z
\foreach
\foreach