有什么巧妙的方法可以递归输入任意数量的行到数学数组中?具体来说,假设我写
\mycommand{A/B, C/D}
然后我得到
\begin{array}{l} A \mapsto B \\ C \mapsto D\end{array}
而如果我简单地写\mycommand{A/B}
,那么我就会得到
\begin{array}{l} A \mapsto B \end{array}
我已经尝试过了
\newcommand*{\mycommand}[1]{ \begin{array}{l} \foreach \xx/\yy in {#1} { \xx \mapsto \yy \\ } \end{array} }
\\
但后来我意识到,每一行新内容都遇到了问题。
答案1
您不能\foreach
以这种方式处理带有循环的行。 原因有二:
- 每个周期按组进行处理
- 无论如何,在细胞内进行这一操作
array
都是行不通的,因为细胞是形成群体的。
以下是一个expl3
实现:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mycommand}{O{c}m}
{
\eric_mycommand:nn { #1 } { #2 }
}
\tl_new:N \l__eric_array_tl
\cs_new_protected:Npn \eric_mycommand:nn #1 #2
{
\tl_clear:N \l__eric_array_tl
\clist_map_inline:nn { #2 }
{
\__eric_process_entry:w ##1 \q_stop
}
\begin{array}[#1]{l@{}l}
\l__eric_array_tl
\end{array}
}
\cs_new_protected:Npn \__eric_process_entry:w #1 / #2 \q_stop
{
\tl_put_right:Nn \l__eric_array_tl { #1 & {} \mapsto #2 \\ }
}
\ExplSyntaxOff
\begin{document}
x $\mycommand{A/B}$ y
x $\mycommand[t]{A/B, C/D, E/F}$ y
\bigskip
x $\mycommand{A/B, C/D, E/F}$ y
\end{document}
可选参数用于的垂直对齐array
。
你\foreach
可以这样做:
\documentclass{article}
\usepackage{pgffor}
\providecommand{\expandonce}[1]{\unexpanded\expandafter{#1}}
\newcommand\mycommand[1]{%
\gdef\mycommandtemp{}%
\foreach \xx/\yy in {#1}{%
\xdef\mycommandtemp{\expandonce{\mycommandtemp}%
\expandonce{\xx} & {} \noexpand\mapsto \expandonce{\yy} \noexpand\\}}
\begin{array}{l@{}l}
\mycommandtemp
\end{array}}
\begin{document}
x $\mycommand{A/B}$ y
\bigskip
x $\mycommand{A/B, C/D, E/F}$ y
\end{document}
答案2
不使用软件包的尝试:
egreg
(更新:这个方法与第二种方法非常相似\foreach
,并使用令牌寄存器而不是临时宏;我还提供了第二种不进行任何分配的方法,现在我已经明白了,如果中间没有任何东西(甚至没有放松)那么\\
在决赛之前\end{array}
是可以的)。
\documentclass{article}
% first method:
\newtoks\ERICtoks
\makeatletter
\newcommand*\ERICarray [1]{\ERICarray@ #1,\ERICarray/,}
\def\ERICarray@ #1/#2,{\ERICtoks={#1\mapsto #2}\ERICarray@@}
\def\ERICarray@@ #1/#2,%
{\ifx\ERICarray#1\ERICarray@end\else
\ERICtoks=\expandafter{\the\ERICtoks\\#1\mapsto#2}\fi\ERICarray@@}
\def\ERICarray@end #1\fi\ERICarray@@%
{\fi\begin{array}{l}\the\ERICtoks\end{array}}
\makeatother
\begin{document}
One line
$\ERICarray{A/B}=
\begin{array}{l}
A\mapsto B
\end{array}$
Two lines
$\ERICarray{A/B, C/D}=
\begin{array}{l}
A\mapsto B\\
C\mapsto D
\end{array}$
Five lines
$\ERICarray{A/B,C/D, E/F,G/H , K/L}=
\begin{array}{l}
A\mapsto B\\ C\mapsto D\\ E\mapsto F\\ G\mapsto H\\ K\mapsto L
\end{array}$
\end{document}
% second method (no assignments, only delimited macros):
\newcommand*\ERICarray [1]{\begin{array}{l}
\ERICarrayLOOP #1,\end{array}\ERICarrayCLEANUP/,}
\def\ERICarrayLOOP #1/#2,{#1\mapsto#2\\\ERICarrayLOOP}
\def\ERICarrayCLEANUP\mapsto\\\ERICarrayLOOP{}