Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
add comment

3 Answers 3

up vote 13 down vote accepted

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

share|improve this answer
    
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
add comment

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.

share|improve this answer
    
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
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.