如何在 \pgfmathsetmacro 之前添加 \global?

如何在 \pgfmathsetmacro 之前添加 \global?

似乎不能\global在 a 之前添加\pgfmathsetmacro,因为会产生以下结果:

不能使用带有‘\begingroup’的前缀。

但这就是我在这里需要的功能。

我正在尝试计算列表中整数的平均值。在 MWE 中,我的列表是

\newcommand*{\MyData}{3,7,X,Y,8,9,Z}%

消息\typeout显示:

**** NumberOfValidEnteries=1, \AverageValue=3.0
**** NumberOfValidEnteries=2, \AverageValue=3.5
**** NumberOfValidEnteries=3, \AverageValue=2.66666
**** NumberOfValidEnteries=4, \AverageValue=2.25

因此看起来好像 正在\pgfmathsetmacro工作,只是它没有在 的连续迭代之间保存其状态\foreach,而这正是\global最初存在的目的。

代码:

\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}

% http://tex.stackexchange.com/questions/50111/how-to-check-if-the-value-of-a-parameter-is-a-number
\newcommand*{\IfIsInteger}[3]{%
    \IfStrEq{#1}{ }{%
        #3% is a blank string
    }{%
        \IfInteger{#1}{#2}{#3}%
    }%
}%

\newcommand*{\MyData}{3,7,X,Y,8,9,Z}%

\newcommand*{\AverageValue}{0}
\newcounter{NumberOfValidEnteries}
\newcommand*{\ComputeAverage}[1]{%
    %% Initialize (in case this is used more than once)
    \renewcommand*{\AverageValue}{0}
    \setcounter{NumberOfValidEnteries}{0}%
    %
    \edef\ExpandedDataEnteries{#1}% So that #1 can be a list or a macro defined list.
    \foreach \NewData in \ExpandedDataEnteries {%
        \IfIsInteger{\NewData}{%
            %\global% <---- I need this ????
            \pgfmathsetmacro{\AverageValue}{%  
                (\AverageValue * \arabic{NumberOfValidEnteries} + \NewData) /
                (\arabic{NumberOfValidEnteries} + 1)
            }%
            \stepcounter{NumberOfValidEnteries}%
            \typeout{**** NumberOfValidEnteries=\arabic{NumberOfValidEnteries}, \string\AverageValue=\AverageValue}%
        }{%
            % Not integer data so skip it
        }%
    }%
}

\begin{document}
    \ComputeAverage{\MyData}%
    Average of integers in ``\MyData" is ``\AverageValue".
\end{document}

答案1

您只能合法地放置\global在赋值命令之前:

\global\def
\global\let
\global\mathchardef
\global\catcode
\global\advance

等等。需要注意的是\global 想要和寻找后面跟着一个合适的命令,进行扩展。例如,etoolbox定义

\newrobustcmd{\cslet}[2]{%
  \expandafter\let\csname#1\endcsname#2}

也是\global\cslet{foo}{\bar}合法的,因为它将成为

\global\expandafter\let\csname foo\endcsname\bar

在第一次扩展之后,但由于\expandafter是可扩展的,\global因此会触发其扩展,并且您可以获得\global\let\foo\bar想要的结果。

另一方面,\pgfmathsetmacro定义pgfmathcalc.code.tex

\def\pgfmathsetmacro#1#2{%
  \begingroup%
    \pgfmathparse{#2}%
        \let#1=\pgfmathresult
    \pgfmath@smuggleone{#1}%
  \endgroup%
}

所以绝对不能\global在它前面添加。

最简单的解决方法是说

\pgfmathparse
  (\AverageValue * \arabic{NumberOfValidEnteries} + \NewData) /
   (\arabic{NumberOfValidEnteries} + 1)
  }%
\global\let\AverageValue\pgfmathresult

因为\pgfmathparse将结果存储在中\pgfmathresult

相关内容