# How to find the length of a PGF array?

A few of my macros currently require the user to pass the length of an array along with the array itself. It would be nice if the length could be calculated for them, as the user in question (myself) seems incapable of consistently counting beyond 3.

I've checked the pgfmanual's chapters 56 (for loops, where most of this is getting used) and 63 (mathematical functions where arrays are defined). In some sense, this is just counting commas (which I don't know how to do), but PGF has a few exceptions in arrays with () and {} allowing entries to have commas within them.

Can someone write a reasonable pgf math function that takes an array as its only argument and returns the length of that array as its result?

-

## 3 Answers

In the cvs version of pgf/tikz or in the version available for texlive at tlcontrib there is an experimental undocumented dim function in pgfmath defined as

\makeatletter
% dim function: return dimension of an array
% dim({1,2,3}) return 3
% dim({{1,2,3},{4,5,6}}) return 2
\pgfmathdeclarefunction{dim}{1}{%
\begingroup
\pgfmath@count=0\relax
\expandafter\pgfmath@dim@i\pgfutil@firstofone#1\pgfmath@token@stop
\edef\pgfmathresult{\the\pgfmath@count}%
\pgfmath@smuggleone\pgfmathresult%
\endgroup}

\def\pgfmath@dim@i#1{%
\ifx\pgfmath@token@stop#1%
\else
\advance\pgfmath@count by 1\relax
\expandafter\pgfmath@dim@i
\fi}

\makeatother


This can however be very slow for large arrays (any suggestions are welcome!).

You can use it this way

\documentclass{standalone}
\usepackage{pgfmath}
\begin{document}
The dimension of $\{1,2,3\}$ is
\pgfmathparse{dim({1,2,3})}\pgfmathresult.

The dimension of $\{1,2,\{3,4\},5\}$ is
\pgfmathparse{dim({1,2,{3,4},5})}\pgfmathresult.
\end{document}


-
Thanks. I had tried to write this myself and failed. I could never get the result to be returned. It would be nice for the manual to have more examples of functions, since returning the number was very difficult. – Jack Schmidt Nov 28 '11 at 21:15
There is a hidden danger in this solution. If there is only 1 element in the array, for example number 10 used as in the provided examples. It will not return 1 as an answer, but it will count the elements of that number and return 2 as an answer. Some examples: The dimension of {10} is 2., The dimension of {"10"} is 2. and The dimension of {{10}} is 1. – karu Aug 1 '14 at 15:21
@karu You're right. Thanks for spotting this. It may be something to fix in the pgfmath parser itself. The internal form of the array {1,2,3} is {{1}{2}{3}} while for the array {1} it is {1} (and IMHO should be {{1}}). But I need some time to dig into it. – cjorssen Aug 2 '14 at 14:19

It is also relatively easy to solve using just TikZ:

\documentclass{article}
\usepackage{tikz}
\newcounter{arraycard}
\def\arrayLength#1{%
\setcounter{arraycard}{0}%
\foreach \x in #1{%
\stepcounter{arraycard}%
}%
\the\value{arraycard}%
}
\begin{document}
\noindent
The length of $\{1,2,3\}$ is \arrayLength{{1,2,3}}.\\
And the length of $\{1,2,\{3,4\},5\}$ \arrayLength{{1,2,{3,4},5}}.
\end{document}


This just uses foreach to iterate over the list and increases a count on every element seen.

-
Is there a specific reason to embed the \foreach loop into a tikzpicture environment? – Daniel Nov 23 '11 at 20:47
@Daniel: Nope, just had some other stuff there first as well. Removed that but left the tikzpic environment. It can be removed without problems (as long as you add comments to prevent spurious spaces). – Roelof Spijker Nov 23 '11 at 21:03
Then I would suggest to remove it from your answer as well; just to make it more concise and precise. – Daniel Nov 23 '11 at 21:10
@Daniel: Excellent point. I have done so. – Roelof Spijker Nov 24 '11 at 7:55

Here is a (community wiki) answer written with great assistance from Bruno Le Floch, Joseph Wright, egreg, and probably a few others on the texsx chat.

\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \Counter #1 \Stopper { \tl_length:n {#1} }
\ExplSyntaxOff
\pgfmathdeclarefunction{countarray}{1}{\edef\pgfmathresult{\Counter#1\Stopper}}


It can be used as in:

\pgfmathtruncatemacro{\Length}{countarray({1,2,3,4})}


Which sets \Length to 4.

-