How to find the length of a PGF array?

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}

dim of an array


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.


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.