我经常需要定义名称包含计数器值的宏,特别是将一个值归于多个对象:在 python 中我会这样做:
myArray[0] = "mystyle"
不幸的是,我不能使用,\expandafter\xdef\csname myArray\the\mycounter\endcsname
因为在 LaTeX 中,宏中不能有数字。现在我正在使用\roman{mycounter}
它,但它感觉很不靠谱,因为计算罗马数字版本可能需要很长时间……有没有更好的解决方案?我特别尝试检查 LaTeX3 是否为这种包含数字的关联数组提供了更好的方法,但我只能找到整数数组(我猜只能包含数组的整数)。我想到的另一种选择可能是元组序列,但访问时间是线性的,效率不高。
平均能量损失
\documentclass[options]{article}
\begin{document}
\newcounter{mycounter}
\expandafter\edef\csname myArray\roman{mycounter}\endcsname{Hello}
``Bonjour'' is ``\csname myArray\roman{mycounter}\endcsname''.
\end{document}
答案1
如果你定义
\def\sdef#1{\expandafter\def\csname#1\endcsname}
\def\cs#1{\csname#1\endcsname}
然后相当于 python 的
myArray[0] = "mystyle"
是
\sdef{myArray[0]}{mystyle}
并且值可以通过以下方式访问
\cs{myArray[0]}
您可以通过声明一个计数器\newcount\mycount
,然后可以通过替换0
字符来扩展上面的示例\the\mycount
:
\newcount\mycount
\sdef{myArray[\the\mycount]}{mystyle}
\cs{myArray[\the\mycount]}
答案2
如果您担心序列的访问时间,您可以使用\csname
:
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\newarray}{m}
{
% keep the next free index
\int_new:c { g__tobias_array_#1_int }
}
\NewDocumentCommand{\addtoarray}{omm}
{
\tobias_array_add:enn
{% the index
\IfNoValueTF { #1 }
{ \int_eval:n { \int_use:c { g__tobias_array_#2_int } } }
{ \int_eval:n { #1 } }
}
{ #2 } % the array
{ #3 }
}
\NewExpandableDocumentCommand{\getarray}{mm}
{
\tobias_array_get:ne { #1 } { \int_eval:n { #2 } }
}
\cs_new_protected:Nn \tobias_array_add:nnn
{
\tl_gclear_new:c { g__tobias_array_#2_#1_tl }
\tl_gset:cn { g__tobias_array_#2_#1_tl } { #3 }
\int_gset:cn { g__tobias_array_#2_int } { #1 + 1 }
}
\cs_generate_variant:Nn \tobias_array_add:nnn { e }
\cs_new:Nn \tobias_array_get:nn
{
\tl_if_exist:cT { g__tobias_array_#1_#2_tl }
{
\tl_use:c { g__tobias_array_#1_#2_tl }
}
}
\cs_generate_variant:Nn \tobias_array_get:nn { ne }
\ExplSyntaxOff
\begin{document}
\newarray{myarray}
\addtoarray{myarray}{An item}
\addtoarray{myarray}{Another item}
\addtoarray[1+3]{myarray}{Item \#4}
0: \getarray{myarray}{0}
1: \getarray{myarray}{1}
3: \getarray{myarray}{3}
4: \getarray{myarray}{2+2}
\end{document}
您可以按顺序添加数组,甚至可以跳过某些索引。并进行算术运算以查找或设置索引。
在示例中,下一个\addtoarray
将使用索引 5。