以编程方式创建一个宏,其名称包含计数器的值

以编程方式创建一个宏,其名称包含计数器的值

我经常需要定义名称包含计数器值的宏,特别是将一个值归于多个对象:在 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。

在此处输入图片描述

相关内容