\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}
\edef\array{5,12,13,14}defines\array(a really bad name as it breaks\begin{array}...) to be the 10 tokens5,12,13,14– David Carlisle Oct 21 '22 at 07:56clistmodule intexdoc interface3but supporting an assignment syntax like\array{3}=5is possible but a lot more complicated and probably not needed compared to say\setarray{3}{5}but you should probably describe your use case and how you want to use this before anyone can suggest a replacement – David Carlisle Oct 21 '22 at 08:10mathlibrary might help you to do what you want. What are you trying to do? – Qrrbrbirlbel Oct 21 '22 at 09:10