我想在循环中从数组中选取一个数字。第一个参数是“起始”值,该值基于第二个和第三个参数 ( \qa
) 每次迭代递增 1。最大迭代次数可由第二个参数 ( ) 确定。\eval@limit
另一个最大值可由第三个参数 ( ) 的值确定\arbitraryarrayvalue
。
我在使用数组时遇到了一些问题\pgfmathdeclarefunction
。具体来说:第一种情况,最简单的情况,就是简单地说:
\pgfmathparse{\myarray[\arbitraryarrayvalue]}
\pgfmath@smuggleone\pgfmathresult
在关闭组之前。事实证明我无法查看数组内部:
Paragraph ended before \pgfflt@readlowlevelfloat was complete.
<to be read again>
\par
因此,查看现有问题后,我发现一个相关问题\pgfflt@readlowlevelfloat
,位于如何使用 pgfmathdeclarefunction 来定义新的 pgf 函数?。
我无法从该问题推断出我的答案。
第二种情况:如果我使用解决方案中的数组Expl3
进行比较(您也可以在下面的代码中找到此解决方案),我会收到如下错误:
File ended while scanning use of \__fp_parse_after:ww.
Emergency stop.
==> Fatal error occurred, no output PDF file produced!
因此,从它们都指“文件在执行某项操作时结束”这一事实来看,我怀疑这些宏会继续读取并进一步扩展,直到文档结束,我通常用一个合适的位置来解决\relax
。我试过在各处添加它(在比较中、在它之后、在数组中等等),但似乎无法摆脱错误。
可能不太相关,但可能是一个通用的解决方案外部 expl3
是答案 (?) 不管怎样,我想看看这种打破循环的通用解决方案在外面是怎样的expl3
。:-)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \breakloop #1 #2
{
\fp_compare:nNnT { #1 } > { #2 }
{ \breakforeach }
}
\ExplSyntaxOff
\global\def\myarray{{5,10,15,20,25,30,35,40,45,50,55,60}}
\makeatletter
\pgfmathdeclarefunction{blah}{3}{%
\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\pgfmathparse{#1} % starting value
\edef\qa{\pgfmathresult}
\pgfmathparse{#2} % maximum amount of loops
\edef\eval@limit{\pgfmathresult}
\pgfmathparse{#3+1} % maximum value of array
\edef\arbitraryarrayvalue{\pgfmathresult}
\foreach \i in {0,...,\eval@limit}
{
\pgfmathparse{\qa+1} % \qa += 1
\global\edef\q@{\pgfmathresult} %
\pgfmathparse{\q@} %
\global\edef\qa{\pgfmathresult} %
\breakloop{\qa}{\myarray[\arbitraryarrayvalue]}
}
\pgfmathparse{\qa}
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\makeatother
\begin{document}
\pgfmathparse{blah(1,1000,9)}\pgfmathresult %
\pgfmathparse{\myarray[2]}\pgfmathresult
\end{document}
答案1
这个问题可以通过首先评估数组元素来解决。获取元素需要传递一个整数作为索引,而不是定点表示法中的数字。我已将数组元素的评估移到循环之外,因为它不会随迭代而变化。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \breakloop #1 #2
{
\fp_compare:nNnT { #1 } > { #2 }
{ \breakforeach }
}
\ExplSyntaxOff
\gdef\myarray{{5,10,15,20,25,30,35,40,45,50,55,60}}
\makeatletter
\pgfmathdeclarefunction{blah}{3}{%
\begingroup
\pgfmathparse{#1} % starting value
\edef\qa{\pgfmathresult}
\pgfmathparse{#2} % maximum amount of loops
\edef\eval@limit{\pgfmathresult}
\pgfmathparse{#3+1} % maximum value of array
\edef\arbitraryarrayvalue{\pgfmathresult}
\pgfmathparse{\myarray[\arbitraryarrayvalue]}
\edef\qb{\pgfmathresult}
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\foreach \i in {0,...,\eval@limit}
{
\pgfmathparse{\qa+1} % \qa += 1
\xdef\q@{\pgfmathresult} %
\pgfmathparse{\q@} %
\xdef\qa{\pgfmathresult} %
\breakloop{\qa}{\qb}
}
\pgfmathparse{\qa}
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\makeatother
\begin{document}
\pgfmathparse{blah(1,1000,9)}\pgfmathresult %
\pgfmathparse{\myarray[4]}\pgfmathresult
\end{document}