\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.

관련 정보