PGF/TikZ: How to store strings in array?
To answer the specific question you are asking, here is a complete minimal example.
\documentclass{standalone}
\usepackage{pgfmath}
\begin{document}
\def\names{{"Katie","Frank","Laura","Joe"}}%
\pgfmathparse{\names[2]}\pgfmathresult
\end{document}
So, you need to use the pgfmath
parser to do the job through \pgfmathparse
and then use the result of the parsing with \pgfmathresult
: in other words, you cannot call \names[2]
directly.
Here is a more complete example with a \foreach
loop:
\documentclass{standalone}
\usepackage{pgfmath,pgffor}
\begin{document}
\def\names{{"Katie","Frank","Laura","Joe"}}%
\foreach \i in {0,...,3} {%
Name \i: \pgfmathparse{\names[\i]}\pgfmathresult, }
\end{document}
This answer may be more generic than specifically relating to TikZ/PGF.
(La)TeX is a macro-based language, so it does not work as expected compared to other languages when dealing with "arrays". For example, while \names[2]
should yield Laura
where
\def\names{Katie, Frank, Laura, Joe}
(indexing from 0), (La)TeX considers [2]
to have no connection to \names
. As such, you're more likely to obtain the output Katie, Frank, Laura, Joe[2]
- a concatenation of \names
(as it is defined) and [2]
.
In order to allow for indexing like one typically would using arrays, you would need some other functionality. Here's an example of a list parser that works like you would expect arrays do:
\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcounter{listtotal}\newcounter{listcntr}%
\NewDocumentCommand{\names}{o}{%
\setcounter{listtotal}{0}\setcounter{listcntr}{-1}%
\renewcommand*{\do}[1]{\stepcounter{listtotal}}%
\expandafter\docsvlist\expandafter{\namesarray}%
\IfNoValueTF{#1}
{\namesarray}% \names
{% \names[<index>]
\renewcommand*{\do}[1]{\stepcounter{listcntr}\ifnum\value{listcntr}=#1\relax##1\fi}%
\expandafter\docsvlist\expandafter{\namesarray}}%
}
\begin{document}
\newcommand{\namesarray}{Katie, Frank, Laura, Joe}%
\verb|\names:|\ \names \par
\verb|\names[2]:|\ \names[2] \par
\verb|\names[0]:|\ \names[0] \par
\verb|\names[5]:|\ \names[5]
\end{document}
The idea here is to store the names in an array \namesarray
and then define a macro (or "function") that takes an optional argument. If no argument is supplied (i.e., you just use \names
), then you print the entire \namesarray
. If an argument is supplied (of the form \names[<index>]
), parse the list sequentially to find that item that matches <index>
and print it.
The list parser relies on etoolbox
's \docsvlist
and enumerator \do
.
The arrayjob
package has some more macros for using the data array.
\documentclass{article}
\usepackage{arrayjob}
\newarray\names
\readarray{names}{Katie&Frank&Laura&Joe}
\begin{document}
\verb|\names(3):|\ \names(3) \par
\verb|\names(1):|\ \names(1) \par
\verb|\names(5):|\ \names(5)
\end{document}
Note:
The arrays are 1 based (index starts at 1
)