![전역을 사용하지 않고 반복 간 및 루프 이후에 효과가 있는 foreach 루프에서 매크로를 정의하는 방법은 무엇입니까?](https://rvso.com/image/254705/%EC%A0%84%EC%97%AD%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80%20%EC%95%8A%EA%B3%A0%20%EB%B0%98%EB%B3%B5%20%EA%B0%84%20%EB%B0%8F%20%EB%A3%A8%ED%94%84%20%EC%9D%B4%ED%9B%84%EC%97%90%20%ED%9A%A8%EA%B3%BC%EA%B0%80%20%EC%9E%88%EB%8A%94%20foreach%20%EB%A3%A8%ED%94%84%EC%97%90%EC%84%9C%20%EB%A7%A4%ED%81%AC%EB%A1%9C%EB%A5%BC%20%EC%A0%95%EC%9D%98%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
를 사용하지 않고 \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
!
편집하다:여기에는 확장된 값이 없고 매크로가 두 개만 있는 새 버전이 있습니다.
\afteriterationdef
현재 반복 후에 매크로를 (재)정의합니다.\afterforeachdef
foreach 이후(및 반복 이후) 매크로를 (재)정의합니다.
다음은 이 두 매크로의 코드입니다.
\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