2

I have a tikz code using values stored in a 1D array, here is a MWE :

\documentclass{standalone}
\usepackage{tikz}

\def \myArray {{0,1,2,3}}

\begin{document}
    \begin{tikzpicture}

        \pgfmathsetmacro\x{\myArray[0]}
        \draw (0,0) node {\x};

    \end{tikzpicture}
\end{document}

So this one works OK for my complex code, but I could really improve it using 2D arrays and loops. Here is a Minimum Not Working Example of what it could look like :

\documentclass{standalone}
\usepackage{tikz}

\def \myArray {{0,1}{2,3}}

\begin{document}
    \begin{tikzpicture}

        \pgfmathsetmacro\x{\myArray[1][1]}
        \draw (0,0) node {\x};

    \end{tikzpicture}
\end{document}

with this code, I'm expecting to have the value "3" displayed (2nd line, 2nd column).

Is there a way to do 2D array storage and indexing with latex/tikz ?

Thomas
  • 1,633

1 Answers1

4

If you are keen on a change of syntax, with expl3 it can be easily done:

\documentclass{standalone}
\usepackage{tikz}

\ExplSyntaxOn \NewDocumentCommand{\definearray}{mm} { \seq_gclear_new:c { g_thomas_array_#1_seq } \seq_set_split:cnn { g_thomas_array_#1_seq } { ; } { #2 } } \NewExpandableDocumentCommand{\retrieve}{mmm} { \clist_item:en { \seq_item:cn { g_thomas_array_#1_seq } { #2 + 1 } } { #3 + 1 } } \cs_generate_variant:Nn \seq_set_split:Nnn { c } \cs_generate_variant:Nn \clist_item:nn { e } \ExplSyntaxOff

\definearray{myarray}{0,1;2,3}

\begin{document}

\begin{tikzpicture} \draw (0,0) node {\retrieve{myarray}{1}{1}}; \end{tikzpicture}

\end{document}

The two +1 are for starting indexing at 0, as usual for PGF arrays (expl3 sequences and comma separated lists start at 1).

A different approach, with a different syntax:

\documentclass{standalone}
\usepackage{tikz}

\ExplSyntaxOn \NewDocumentCommand{\definearray}{mm} { \tl_gclear_new:c { g_thomas_array_#1_tl } \tl_gset:cn { g_thomas_array_#1_tl } { #2 } } \NewExpandableDocumentCommand{\retrieve}{mmm} { \clist_item:en { \tl_item:cn { g_thomas_array_#1_tl } { #2 + 1 } } { #3 + 1 } } \cs_generate_variant:Nn \clist_item:nn { e } \ExplSyntaxOff

\definearray{myarray}{{0,1}{2,3}}

\begin{document}

\begin{tikzpicture} \draw (0,0) node {\retrieve{myarray}{1}{1}}; \end{tikzpicture}

\end{document}

In either case, here's the output:

enter image description here

egreg
  • 1,121,712
  • Is there a way to do the same using nested comma lists? Perhaps start with \def\matrix{{1,2},{3,4}} and then use clist_item:cn {#1} {#2} to get, for example, {1,2} and then after setting some new clist variable equal to this use #3 to get one of the two elements. Something like this could be used to access elements from multidimensional arrays stored as nested comma lists... – Ted Black Jun 02 '23 at 20:54
  • @TedBlack I'll add it. – egreg Jun 02 '23 at 21:18
  • Many thanks. Sorry for the repeated novice questions: no matter how hard I try something like \clist_set:Nn \l_tmpa_clist {\clist_item:cn {#1} {#2}} and then use \clist_item:Nn \l_tmpa_clist {#3} does not work. The program treats \l_tmpa_clist as a single token. My understanding of clists is obviously very poor but can you help me understand the main problem with my thinking? – Ted Black Jun 02 '23 at 21:34
  • @TedBlack Sorry, but \clist_set:Nn \l_tmpa_clist {\clist_item:cn {#1} {#2}} is not going to work. For several reasons. Actually this is understatement… – egreg Jun 02 '23 at 22:24
  • Yes it definitely does not work! Sounds like I need to study this a lot more... – Ted Black Jun 02 '23 at 22:39