如果不使用\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