我定义了一个包含 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}