朋友们,当我必须迭代列表元素时,我曾经非常痛苦,但多亏了 egreg 的建议,我已经成功地使用该etoolbox
包完成了这项任务,例如:
\DeclareListParser*{\dothedance}{;}
\dothedance{\fbox}{item1; item2; item3}
现在,我尝试获取两个列表的笛卡尔积的所有对(请原谅以下 Haskell 代码):
Prelude> [ (x,y) | x <- ['A','B','C'], y <- ['a','b','c','d'] ]
[('A','a'),('A','b'),('A','c'),('A','d'),('B','a'),('B','b'),('B','c'),('B','d'),('C','a'),('C','b'),('C','c'),('C','d')]
然后,对于每一对,我想将其分成两个参数(X和是)并将它们传递给命令。
例如,考虑两个列表[Hello, Howdy]
和[Ann, Mary, Kate]
以下虚拟命令:
\newcommand\saysomething[2]{#1~#2}
我希望每对都是该命令的参数。因此输出将是:
Hello Ann
Hello Mary
Hello Kate
Howdy Ann
Howdy Mary
Howdy Kate
我很确定etoolbox
可以帮我解决这个问题,但我尝试遍历两个列表的所有尝试都失败了。我可能忽略了一些显而易见的东西,但我需要启发。有什么想法吗?
答案1
这可能更优雅......
\documentclass{article}
\usepackage{etoolbox}
\DeclareListParser*{\dothedance}{,}
\newcommand{\saysomething}[2]{#1~#2\par}
\newcommand{\sayitto}[1]{%
\dothedance{\saysomething{#1}}{Ann, Mary, Kate}
}
\begin{document}
\dothedance{%
\sayitto
}{Hello, Howdy}
\end{document}
生成:
Hello Ann
Hello Mary
Hello Kate
Howdy Ann
Howdy Mary
Howdy Kate
(回应评论)为了使得可以在调用时指定两个列表:
\documentclass{article}
\usepackage{etoolbox}
\DeclareListParser*{\dothedance}{,}
\DeclareListParser*{\dotheotherdance}{,}
\newcommand{\saysomething}[2]{#1~#2\par}
\newcommand{\sayitto}[1]{%
\dothedance{\saysomething{#1}}
}
\newcommand{\dothetwostep}[3]{%
\def\partner##1{%
\dothedance{#1{##1}}{#3}%
}
\dothedance{\partner}{#2}
}
\begin{document}
\dothetwostep{\saysomething}{Hello, Howdy}{Ann, Mary, Kate}
\end{document}
答案2
为什么不 :
\documentclass{article}
\usepackage{pgffor}
\newcommand{\saysomething}[2]{
\foreach \w in #1{%
\foreach \n in #2{%
\w~\n \par}}}
\begin{document}
\def\Lone{ Hello, Howdy}
\def\Ltwo{ Ann, Mary, Kate}
\saysomething{\Lone}{\Ltwo}
\end{document}
答案3
这是另一种etoolbox
遵循 Paulo Cereda 的起源思想(直接嵌套循环)的解决方案。
我添加了一个\directprodM
以允许 csv 列表作为宏名称。
\documentclass{article}
\usepackage{etoolbox}
% #1 is a function
% #2 and #3 are literal csv lists
\newcommand\directprod[3]{%
\renewcommand\do[1]{%
\begingroup
\renewcommand\do[1]{%
#1{##1}{####1}}% awful, indeed
\docsvlist{#3}%
\endgroup}%
\docsvlist{#2}}
% #2 and #3 are macros
\newcommand\directprodM[3]{%
\edef\next{\noexpand\directprod\noexpand#1{#2}{#3}}%
\next}
\begin{document}
\newcommand\saysomething[2]{#1~#2\par}
\directprod\saysomething{Hello, Howdy}{Ann, Mary, Kate}
or using macros for lists:
\newcommand\listA{Hello, Howdy}
\newcommand\listB{Ann, Mary, Kate}
\directprodM\saysomething\listA\listB
\end{document}