전역을 사용하지 않고 반복 간 및 루프 이후에 효과가 있는 foreach 루프에서 매크로를 정의하는 방법은 무엇입니까?

전역을 사용하지 않고 반복 간 및 루프 이후에 효과가 있는 foreach 루프에서 매크로를 정의하는 방법은 무엇입니까?

를 사용하지 않고 \global다음 코드를 사용합니다.

\documentclass{minimal}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{etextools}

\newcommand\appendbyforeach[2]{%
  \AfterGroup*{\noexpand\AfterGroup{\noexpand\edef\noexpand#1{\noexpand#1#2}}}
}

\newcommand\defincbyforeach[2]{%
  \AfterGroup*{\noexpand\def\noexpand#1{#2}}
  \AfterGroup*{\noexpand\AfterGroup{\noexpand\def\noexpand#1{#2}}}
}

\newcommand\meaningwithname[1]{\textbackslash#1: \expandafter\meaning\csname #1\endcsname}

\newcommand\mymacro{
  \begingroup
  \def\myarray{init}
  \def\valmax{0}
  \foreach \i in {1,8,-3}{
    \appendbyforeach{\myarray}{,\i}
    \pgfmathsetmacro{\max}{\valmax < \i ? \i : \valmax}
    \defincbyforeach\valmax{\max}
    %%% print state of \myarray and \valmax
    foreach \i\\\meaningwithname{myarray}\\\meaningwithname{valmax}\par
  }
  inside\\\meaningwithname{myarray}\\\meaningwithname{valmax}\par
  \endgroup
  outside\\\meaningwithname{myarray}\\\meaningwithname{valmax}\par
}

\begin{document}\mymacro\end{document}

다음을 포함하는 문서를 생성합니다.

    foreach 1
\myarray: 매크로:->초기화
\valmax: 매크로:->0
    foreach 8
\myarray: 매크로:->초기화
\valmax: 매크로:->1.0
    foreach -3
\myarray: 매크로:->초기화
\valmax: 매크로:->8.0
    내부에
\myarray: 매크로:->init,1,8,-3
\valmax: 매크로:->8.0
    밖의
\myarray: \휴식
\valmax: \휴식

이 결과는 나에게 잘 맞는다!

하지만 동일한 효과를 얻으면서 매크로 \appendbyforeach를 정의하는 더 좋은 방법이 있을까요 ?\defincbyforeach

etextools여기 패키지가 정말 실용적인가요 ?

답변1

메모:이 코드는 항상 etextools. 내 질문에 대한 답변을 수락하기 전에 다른 사람들이 나에게 더 흥미로운 솔루션(없이 etextools, 더 효과적이고, 더 빠르고, 더 간단한...) 을 제공해주기를 바랍니다 . 하지만 항상 사용하지 않고 \global!

편집하다:여기에는 확장된 값이 없고 매크로가 두 개만 있는 새 버전이 있습니다.

  1. \afteriterationdef현재 반복 후에 매크로를 (재)정의합니다.

  2. \afterforeachdefforeach 이후(및 반복 이후) 매크로를 (재)정의합니다.

다음은 이 두 매크로의 코드입니다.

\documentclass{minimal}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{etextools}

\makeatletter

% define a macro after current iteration
\newcommand\afteriterationdef[1]{\aftergroup@def#1}

% define a macro after foreach (and after iteration)
\newcommand\afterforeachdef[1]{\afteriterationdef{#1}\AfterGroup{\aftergroup@def#1}}

\makeatother

그리고 예를 들면:

\newcommand\meaningwithname[1]{%
  \textbackslash#1: \expandafter\meaning\csname #1\endcsname}

\newcommand\mymacro{
  {
    \def\myarray{init}
    \def\myvalue{1}
    \foreach \i in {1,8,-3,-1}{
      % append some value to \myarray
      \edef\myarray{\myarray,\i}
      \afterforeachdef\myarray
      % incremental definition of \mtvalue
      \pgfmathsetmacro{\myvalue}{\myvalue*\i}
      \afterforeachdef\myvalue
      %%% print meaning of \myarray and \myvalue at each iteration
      foreach \i: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
    }
    %%% print meaning of \myarray and \myvalue after \foreach
    inside group: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
  }
  %%% print meaning of \myarray and \myvalue outside
  outside group: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
}

\begin{document}\mymacro\end{document}

이 예에서는 다음 텍스트를 생성합니다.

foreach 1: \myarray: 매크로:->init,1, \myvalue: 매크로:->1.0
foreach 8: \myarray: 매크로:->init,1,8, \myvalue: 매크로:->8.0
foreach -3: \myarray: 매크로:->init,1,8,-3, \myvalue: 매크로:->-24.0
foreach -1: \myarray: 매크로:->init,1,8,-3,-1, \myvalue: 매크로:->24.0
내부 그룹: \myarray: 매크로:->init,1,8,-3,-1, \myvalue: 매크로:->24.0
외부 그룹: \myarray: \relax, \myvalue: \relax

편집 2:두 개의 중첩된 또 다른 예 \foreach:

\newcommand\mymacrowithnestedforeach{
  {
    \def\myarray{init}
    \def\myvalue{1}
    \foreach \i in {1,...,3}{
      \foreach \j in {1,...,3}{
        % append some value to \myarray
        \edef\myarray{\myarray,(\i,\j)}
        \afterforeachdef\myarray
        % incremental definition of \myvalue
        \pgfmathsetmacro{\myvalue}{\myvalue+\j*\i}
        \afterforeachdef\myvalue
        %%% print meaning of \myarray and \myvalue at each iteration
        int foreach \i: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
      }
      % 
      \afterforeachdef\myarray
      \afterforeachdef\myvalue
      %%% print meaning of \myarray and \myvalue at each iteration
      ext foreach \i: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
    }
    %%% print meaning of \myarray and \myvalue after \foreach
    inside  group: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
  }
  %%% print meaning of \myarray and \myvalue outside
  outside group: \meaningwithname{myarray}, \meaningwithname{myvalue}\par
}

\begin{document}\mymacrowithnestedforeach\end{document}

이 예에서는 다음 텍스트를 생성합니다.

int foreach 1: \myarray: 매크로:->init,(1,1), \myvalue: 매크로:->2.0
int foreach 1: \myarray: 매크로:->init,(1,1),(1,2), \myvalue: 매크로:->4.0
int foreach 1: \myarray: 매크로:->init,(1,1),(1,2),(1,3), \myvalue: 매크로:->7.0
ext foreach 1: \myarray: 매크로:->init,(1,1),(1,2),(1,3), \myvalue: 매크로:->7.0
int foreach 2: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1), \myvalue: 매크로:->9.0
int foreach 2: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2), \myvalue: 매크로:-> 13.0
int foreach 2: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3), \ myvalue: 매크로:->19.0
ext foreach 2: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3), \ myvalue: 매크로:->19.0
int foreach 3: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),( 3,1), \myvalue: 매크로:->22.0
int foreach 3: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),( 3,1),(3,2), \myvalue: 매크로:->28.0
int foreach 3: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),( 3,1),(3,2),(3,3), \myvalue: 매크로:->37.0
ext foreach 3: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),( 3,1),(3,2),(3,3), \myvalue: 매크로:->37.0
내부 그룹: \myarray: 매크로:->init,(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3 ,1),(3,2),(3,3), \myvalue: 매크로:->37.0
외부 그룹: \myarray: \relax, \myvalue: \relax

관련 정보