# How can I determine the size of an array?

After a long search period, I was not able to figure out how to determine and use the len of an array like this:

\def\mar{ 1,2 }
\path let \p1=($(rec.west)-(rec.east)$),
\p2=($(rec.north)-(rec.south)$),
\p3=($len{\mar}$),
\n1 = {veclen(\p1)*0.16}                  %width
,\n2 = {veclen(\p2)/\p3}                    %height
in node[mynode,
minimum width=\n1
,minimum height=\n2
,anchor=north west
] at (rec.north west) {foobar
};

• \p3 needs to be a point but you are assigning a number. Also as far as I know there is no array counter yet (Maybe in the CVS version). What exactly do you want to do with \p3? – percusse Aug 6 '12 at 22:37
• I like to divide the height by the lenght of my array. – drh Aug 6 '12 at 22:41
• With TikZ/pgf, \mar is a simple list. An array should be defined by \def{{1,2}} (p.529, section 63.1, pgfmanual v2.10). – Paul Gaborit Aug 7 '12 at 8:11

I'm not aware of any array length counter in TikZ (it might have been introduced in the CVS version). So getting some help from the xstring package, we count the commas and add one to it.

\documentclass{article}
\usepackage{tikz,xstring}
\usetikzlibrary{calc}
\def\mar{1,2,4,5,7}
\StrCount{\mar}{,}[\arrlength]

\begin{document}
\begin{tikzpicture}
\node[draw,minimum width=2cm,minimum height=5cm] (rec) at (2cm,1cm) {rec};
\path let \p1=($(rec.west)-(rec.east)$),
\p2=($(rec.north)-(rec.south)$),
\n{arrlen}={\arrlength+1},
\n1 = {veclen(\p1)*0.16},           %width
\n2 = {veclen(\p2)/\n{arrlen}}      %height
in node[draw,
minimum width=\n1
,minimum height=\n2
,anchor=north west
] at (rec.north west) {foobar
};
\end{tikzpicture}
I have found \arrlength\space commas in the array.
\end{document} Like PolGab wrote in his comment, you have some possibilities to use an array with pgfmath. Here some examples from the pgfmanual :

\def\myarray{{7,-3,4,-9,11}}
\pgfmathparse{\myarray} \pgfmathresult

\def\print#1{\pgfmathparse{#1}\pgfmathresult}
\def\identitymatrix{{{1,0,0},{0,1,0},{0,0,1}}}
\tikz[x=0.5cm,y=0.5cm]\foreach \i in {0,1,2} \foreach \j in {0,1,2}
\node at (\j,-\i) [anchor=base] {\print{\identitymatrix[\i][\j]}};

\pgfmathparse{array({9,13,17,21},2)} \pgfmathresult


Bad news : len of an array does not exist in pgfmath. It's not very complex to add this possibility to pgfmath. Here a simple way without a new package. It's not very efficient but it's simple.

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\def\getlen#1{%
\pgfmathsetmacro{\lenarray}{0}%
\foreach \i in #1{%
\pgfmathtruncatemacro{\lenarray}{\lenarray+1}%
\global\let\lenarray\lenarray}%
}

\begin{tikzpicture}
\node[draw,minimum width=2cm,minimum height=5cm,fill=blue!30,opacity=.5 ] (rec) at (2cm,1cm) {REC};
\def\mar{1,2}
\getlen{\mar}
\path let \p1=($(rec.west)-(rec.east)$),
\p2=($(rec.north)-(rec.south)$),
\n1 = {veclen(\p1)*0.16},
\n2 = {veclen(\p2)/\lenarray}
in node[draw,minimum width  = \n1,
minimum height = \n2,
anchor=north west,fill=orange!30,opacity=.5
] at (rec.north west) {foobar};
\end{tikzpicture}

\end{document} • This seems not to work with {10,20,...,180} construct? If I am correct how to make that work? – Matthias Arras Jan 30 '20 at 13:16
• @MatthiasArras I think it's normal. {10,20,...,180} construct is useful with \foreach but here it's difficult to use – Alain Matthes Jan 30 '20 at 13:55
• Oh yes it works as expected, I was under the impression that \getlen would return the number. But \lenarray does. So indeed \getlen{{1,2,...,10}}\lenarray works and outputs 10. – Matthias Arras Jan 30 '20 at 14:35

The following uses a \foreach loop to count the number of members and ignores an empty members as the result of extraneous commas. So for a definition such as

\def\mar{1,2 , 4,, 5 ,7,,,}


this reports 5 members: ## Code:

\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}
\usetikzlibrary{calc}

\def\mar{1,2 , 4,, 5 ,7,,,}

\makeatletter
\newcounter{@LengthOfArray}%
\newcommand{\GetArrayLength}{\arabic{@LengthOfArray}}%
\newcommand*{\SetArrayLength}{%
% Counts the number of array members. This ignore any empty
% array members created by extraneous commas (such as those
% as  result of a double comma, or a trailing comma.
\setcounter{@LengthOfArray}{0}%
\foreach \x in #1 {%
\IfStrEq{\x}{}{}{% only increment when non-empty
\stepcounter{@LengthOfArray}%
}%
}%
}%
\makeatother

\begin{document}
\SetArrayLength{\mar}
\begin{tikzpicture}
\node[draw,minimum width=2cm,minimum height=5cm] (rec) at (2cm,1cm) {rec};
\path let \p1=($(rec.west)-(rec.east)$),
\p2=($(rec.north)-(rec.south)$),
\n{arrlen}={\GetArrayLength},
\n1 = {veclen(\p1)*0.16},           %width
\n2 = {veclen(\p2)/\n{arrlen}}      %height
in node[draw,
minimum width=\n1
,minimum height=\n2
,anchor=north west
] at (rec.north west) {foobar
};
\end{tikzpicture}

\Large
There are \GetArrayLength\space members in the array.
\end{document}