15

I'm trying a small educational example using pgfmath. I want to calculate the minimum of a list of numbers.

More accurately, I have a list of (number,string)-pairs, and I want the minimum of all the numbers.

My \calculateMin command (see below) first uses a \foreach loop to build up a temporary list comprising just the first components. It then takes the minimum of that using pgfmath's built-in min function.

Code

\documentclass{article}

\usepackage{tikz}

\begin{document}

\newcommand*\calculateMin[1]{%
  \def\mylist{}%
  \foreach \i/\j in {#1} {%
    \edef\mylist{\mylist,\i}%
  }%
  \pgfmathparse{min(\mylist)}\pgfmathresult%
}

Minimum of (8/ignore,7/this,2/second,5/component) 
is \calculateMin{8/ignore,7/this,2/second,5/component}.

\end{document}

Result

Minimum of (8/ignore,7/this,2/second,5/component) is 16383.0.

The result should be "2". What's going on?

1 Answers1

17

This happens because you're calling min with an argument it's not made for: The first element of your list is empty, which sets \pgfmathresult to the largest allowable number, due to the way the algorithm is implemented.

To get the correct behaviour, you should make sure the first component is not empty (the last one may be, though). Also, \foreach introduces groups, so the macro won't actually be updated if you only use \edef. Use \xdef (an alias for \global\edef) instead:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\newcommand*\calculateMin[1]{%
  \def\mylist{}%
  \foreach \i/\j in {#1} {%
    \xdef\mylist{\i,\mylist}%
  }%
  \pgfmathparse{min(\mylist)}\pgfmathresult%
}

Minimum of (8/ignore,7/this,2/second,5/component) 
is \calculateMin{8/ignore,7/this,2/second,5/component}.


\end{document}

Jake
  • 232,450