![模拟“元组”数据结构(当您可以自由选择语法时)](https://linux22.com/image/247389/%E6%A8%A1%E6%8B%9F%E2%80%9C%E5%85%83%E7%BB%84%E2%80%9D%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E5%BD%93%E6%82%A8%E5%8F%AF%E4%BB%A5%E8%87%AA%E7%94%B1%E9%80%89%E6%8B%A9%E8%AF%AD%E6%B3%95%E6%97%B6%EF%BC%89.png)
如何在 LaTeX 中实现“元组”数据结构?其思想是将多个元素(可能是预定义的数字)存储在一个宏中,然后能够通过索引(数字或其他)提取每个元素。
\documentclass{article}
% HOW TO IMPLEMENT THIS?
\newcommand{\definetuple}[...]{...}
\newcommand{\extractfromtuple}[...]{...}
% HOW TO IMPLEMENT THIS?
% YOU ARE FREE TO CHANGE SYNTAX HERE
\definetuple{first}{Alice}{Munich}{Germany}
\definetuple{second}{Bob}{London}{United Kingdom}
\begin{document}
\extractfromtuple{first}{1} lives in \extractfromtuple{first}{2}
which is located in \extractfromtuple{first}{3};
this may or may not be true for \extractfromtuple{second}{1}.
\end{document}
% YOU ARE FREE TO CHANGE SYNTAX HERE
我想拆分原始问题这样,具有新 API 的优秀解决方案就有了容身之地。这应该是社区 wiki 吗?
答案1
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\definetuple}{mmmm}
{
\tl_new:c { g_tuple_#1_tl }
\tl_gset:cn { g_tuple_#1_tl } { {#2} {#3} {#4} }
}
\DeclareExpandableDocumentCommand{\extractfromtuple}{mm}
{
\tl_item:cn { g_tuple_#1_tl } { #2-1 }
}
\ExplSyntaxOff
\begin{document}
\definetuple{alice}{Alice}{Munich}{Germany}
\definetuple{bob}{Bob}{London}{United Kingdom}
\extractfromtuple{alice}{3}
\extractfromtuple{bob}{1}
\end{document}
在这个简单的例子中,我使用了一个标记列表;对于更复杂的任务,也许序列会更好。
另一种方法可能是使用属性列表。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\definetuple}{mmmm}
{
\prop_new:c { g_tuple_#1_prop }
\prop_gput:cnn { g_tuple_#1_prop } { name } {#2}
\prop_gput:cnn { g_tuple_#1_prop } { town } {#3}
\prop_gput:cnn { g_tuple_#1_prop } { country } {#4}
}
\DeclareExpandableDocumentCommand{\extractfromtuple}{mm}
{
\prop_get:cn { g_tuple_#1_prop } { #2 }
}
\ExplSyntaxOff
\begin{document}
\definetuple{alice}{Alice}{Munich}{Germany}
\definetuple{bob}{Bob}{London}{United Kingdom}
\extractfromtuple{alice}{country}
\extractfromtuple{bob}{name}
\end{document}
这里可用的键是name
、town
和country
。我更喜欢这种方法来完成更复杂的任务,例如,每次添加一条信息;例如,可以定义
\NewDocumentCommand{\addtotuple}{mmm}
{
\prop_gput:cnn { g_tuple_#1_prop } { #2 } { #3 }
}
并将\addtotuple{alice}{town}{Berlin}
爱丽丝移到北方。
答案2
这是一个类似于 Python 的元组的通用解决方案,只需六行 TeX 代码即可。
\documentclass{article}
\makeatletter
\def\tuple#1=(#2 #3 #4){%
\expandafter\def\csname#1@1\endcsname{#2}
\expandafter\def\csname#1@2\endcsname{#3}
\expandafter\def\csname#1@3\endcsname{#4}
}
\def\xtuple#1#2{%
\csname#1@#2\endcsname
}
\makeatother
\begin{document}
% example add
\tuple firstauthor=(Alice Munich Germany)
\tuple secondauthor=(Bob London United Kingdom)
% example print
\xtuple{firstauthor}{1}
\xtuple{secondauthor}{3}
\end{document}
就像在 Python 中空间很重要一样:) 您添加一个三元组(您的结构由三元组组成,正如您所指出的不是元组):
\tuple firstauthor=(Alice Munich Germany)
可以按如下方式访问 n 元素:
\xtuple{firstauthor}{1}
\xtuple{secondauthor}{3}
如果我们为颜色定义一个三元组,那么结构会更容易理解,
\tuple red=(255 0 0)
\xtuple{red}{1}
可以相当容易地添加更多操作。