# Is there a way to perform “if” check only once instead of every iteration in a loop?

The \zNonZero is equal to 0 if #1 is 0, but is equal to 1 if #1 is greater than 0. The problem is, the if check inside the loop is performed every iteration: I need it to be performed only once (for the first iteration). Is there a way to get rid of unneeded checks?

\begin{document}
\parindent0pt
\newcount\zNonZero
\def\zLoop#1%
{ \zNonZero1
\ifnum#1<1 % HOW TO CHECK THIS ONLY ONCE?
\zNonZero0
\fi
\ifnum#1<5
#1...(\the\zNonZero)\newline
\expandafter\zLoop\expandafter{\the\numexpr#1+1\relax}
\fi
}
\zLoop{0}
\end{document}


The "if" check is done 5 times here, but we need it to be done only once:

• Is this your real code or is your actual test more expensive? I don't think this simple test will have any performance impact even for a larger number of iterations. – siracusa Jul 12 at 18:32
• You could create two separate functions. One that processes the first iteration and does the "if" check, and something that processes subsequent iterations. – Werner Jul 12 at 18:33

Detach the first conditional.

\documentclass{article}

\newcount\zNonZero

\def\zLoop#1{%
\zNonZero=1
\zLoopStart{#1}%
\zLoopLoop{#1}%
}
\def\zLoopStart#1{%
\ifnum#1<1 % HOW TO CHECK THIS ONLY ONCE?
\zNonZero=0
\fi
}
\def\zLoopLoop#1{%
\ifnum#1<5
#1...(\the\zNonZero)\par
\zNonZero=1
\expandafter\zLoopLoop\expandafter{\the\numexpr#1+1\expandafter\relax\expandafter}%
\fi
}

\setlength{\parindent}{0pt}

\begin{document}

\zLoop{0}

\end{document}


Note the two more \expandafter tokens so the entire conditional is removed before the loop is restarted.

This possibly doesn't qualify, but I'll mention it anyway.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\zLoop}{m}
{
\bp_zloop:n { #1 }
}
\cs_new:Nn \bp_zloop:n
{
\int_compare:nT { #1 < 5 }
{
#1...(\int_eval:n { \int_min:nn { #1 } { 1 } })\par
\bp_zloop:f { \int_eval:n { #1 + 1 } }
}
}
\cs_generate_variant:Nn \bp_zloop:n { f }

\ExplSyntaxOff

\begin{document}

\zLoop{0}

\end{document}

\documentclass{article}
\begin{document}
\parindent0pt
\newcount\zNonZero
\newif\ifCheck \Checktrue
\def\zLoop#1{%
\zNonZero1
\ifCheck\ifnum#1<1 \zNonZero0 \fi\Checkfalse\fi
\ifnum#1<5
#1...(\the\zNonZero)\newline
\expandafter\zLoop\expandafter{\the\numexpr#1+1\relax}
\fi
\Checktrue
}
\zLoop{0}
\end{document}

• ...this still performs a conditional check \ifCheck with every call of \zLoop. – Werner Jul 12 at 19:17
• @Werner in case the \ifnum#1<1 is a placeholder for a test that is actually more expensive then this could actually be faster - maybe in practise it does not make a difference but at least in theory it is a good idea. – Marijn Jul 13 at 10:32