定义了一个数组但它被当作一个普通字符串

定义了一个数组但它被当作一个普通字符串

我定义了一个包含 4 个整数的数组。我访问了第 3 个元素,修改了最后一个元素,然后访问了它。但是 Latex 并没有执行数组操作,而是简单地用\array整个数组替换了 的每个实例。我应该如何修改我的代码以使其按预期工作?

\documentclass{article}
\usepackage{tikz}
\begin{document}

\edef\array{5,12,13,14}

\array{2} \\
\array{3}=5 \\
\array{3}
\end{document}

预期的:

13
5

现实:

5,12,13,142
5,12,13,143=5
5,12,13,143

答案1

你可以做

\def\foo{5,12,13,14}

但这不会神奇地为您提供一些数组。在某些脚本语言中,变量所赋的值也可以键入相同的变量。但 TeX 只有宏和寄存器,而上面的代码只是定义了一个不带参数的宏。

请注意,我将您的更改\array\foo因为\array在 LaTeX 中是预定义的,并且对于数学构造来说是一个非常非常重要的命令。

如果你输入\foo{2},TeX 只会排版

5,12,13,142

因为它的工作方式是这样的:宏\foo被扩展并且替换文本被简单地放入输入流中。

仅仅因为某件事在 Perl 中以某种方式完成并不意味着在 Python 中也能完成。TeX 语言编程比 Perl 和 Python 更有趣。

您想在 LaTeX 中模拟数组吗?分配、设置和更改它们的值?这当然是可能的。

\documentclass{article}

\ExplSyntaxOn

%%% User interface
\NewDocumentCommand{\newarray}{m}
 {
  \nver_array_new:n { #1 }
 }

\NewDocumentCommand{\setarray}{mom}
 {
  \IfNoValueTF { #2 }
   {
    \nver_array_set:nn { #1 } { #3 }
   }
   {
    \nver_array_change:nnn { #1 } { #2 } { #3 }
   }
 }

\NewExpandableDocumentCommand{\getfromarray}{mm}
 {
  \nver_array_get:nn { #1 } { #2 }
 }

\NewExpandableDocumentCommand{\lengthofarray}{m}
 {
  \nver_array_length:n { #1 }
 }

%%% Public functions
\cs_new_protected:Nn \nver_array_new:n
 {
  \seq_new:c { l__nver_array_#1_seq }
 }

\cs_new_protected:Nn \nver_array_set:nn
 {
  \seq_set_split:cnn { l__nver_array_#1_seq } { , } { #2 }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { c }

\cs_new_protected:Nn \nver_array_change:nnn
 {
  \int_compare:nTF { \seq_count:c { l__nver_array_#1_seq } < #2 }
   {% we need to add empty items
    \__nver_array_append:nnn { #1 } { #2 } { #3 }
   }
   {% we need to change a value
    \__nver_array_change:nnn { #1 } { #2 } { #3 }
   }
 }

\cs_new:Nn \nver_array_get:nn
 {
  \seq_item:cn { l__nver_array_#1_seq } { #2 }
 }

\cs_new:Nn \nver_array_length:n
 {
  \seq_count:c { l__nver_array_#1_seq }
 }

%%% Private functions and variables

\seq_new:N \l__nver_array_in_seq
\seq_new:N \l__nver_array_out_seq

\cs_new_protected:Nn \__nver_array_append:nnn
 {
  \int_step_inline:nnn
   { \seq_count:c { l__nver_array_#1_seq } + 1 } % start from the end
   { #2 - 1 } % just before the index
   { \seq_put_right:cn { l__nver_array_#1_seq } {} } % add empty items
  % now we can add the new item
  \seq_put_right:cn { l__nver_array_#1_seq } { #3 }
 }

\cs_new_protected:Nn \__nver_array_change:nnn
 {% we need to change a value
  \seq_set_eq:Nc \l__nver_array_in_seq { l__nver_array_#1_seq }
  \seq_clear:N \l__nver_array_out_seq
  \int_step_inline:nn { \seq_count:N \l__nver_array_in_seq }
   {
    \int_compare:nTF { ##1 = #2 }
     {% the item we want to change
      \seq_put_right:Nn \l__nver_array_out_seq { #3 }
     }
     {% copy the existing value
      \seq_put_right:Nx \l__nver_array_out_seq { \seq_item:Nn \l__nver_array_in_seq { ##1 } }
     }
   }
  \seq_set_eq:cN { l__nver_array_#1_seq } \l__nver_array_out_seq
 }

\ExplSyntaxOff

\begin{document}

\newarray{foo}
\setarray{foo}{3,12,13,14}

Second item in \texttt{foo} is ``\getfromarray{foo}{2}''

\setarray{foo}[2]{5} % change the value of the second item

Second item in \texttt{foo} is ``\getfromarray{foo}{2}''

The array \texttt{foo} has \lengthofarray{foo} items

\setarray{foo}[10]{Tenth item!}

Tenth item in \texttt{foo} is ``\getfromarray{foo}{10}''

The array \texttt{foo} has \lengthofarray{foo} items

\end{document}

可选参数 in\setarray告诉 TeX 必须更改某个项目。如果索引大于调用时数组的长度,则会插入额外的空项目。

在此处输入图片描述

答案2

如果要使用TiKZ数组,则应使用两个括号来定义它。定义后,您可以访问元素并进行读取,但我不知道如何更改其值:

注意:egreg广告中说使用\array是一个危险的想法,所以我改成了\myarray。还Ulrike Fischer宣传了 关于def,并将其改为\newcommand

\documentclass{article}
\usepackage{tikz}
\begin{document}

\newcommand\myarray{{5,12,13,14}}

\pgfmathparse{\myarray[2]}\pgfmathresult \\
%\array[3]=5 \\
\pgfmathparse{\myarray[0]}\pgfmathresult \\
\end{document}

在此处输入图片描述

相关内容