6

I'm trying to test whether an element in a defined list (array) is "empty." I tried using the \empty macro, or putting white spaces inside the quote, but nothing seems to work. I'm testing the emptiness of each element using the etoolbox \ifboolexpr construct with test (also, I tested \notblank with the same results), although I'm not sure if the fault lies in the conditional evaluation or in the \pgfmathparse that retrieves the element from the array.

Thus, what is the correct way of checking if the element is empty and branching into the else part of the conditional.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{etoolbox}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}
\def\n{5}
\def\weights{{"1","2","3","4","","n"}}
\foreach \i [count=\c] in {0,...,\n}{
  \pgfmathparse{\weights[\i]} \let\label\pgfmathresult
  \ifboolexpr{ not test{\ifstrempty{\label}} }{%
    \node at (0,\c) {$l_{\label}$};
  }{ %
    \node at (0,\c) {empty};
  }
}
\end{tikzpicture}
\end{document}
adn
  • 11,233

3 Answers3

4

Below, I have defined the macro \GetNthMember to get the nth member of a list. If node does not exist or is "", then it is displayed in red:

enter image description here

Notes:

  • Your list members are not empty when you define them as "". They have a value which is two double quotes.
  • If you eliminate the double quotes around your list members, one way you can test for an empty member is:

    \IfEq{<string to test>}{}{<true code>}{<false code>}
    

    or if you prefer to still use the double quotes you can compare as:

    \IfEq{<string to test>}{""}{<true code>}{<false code>}
    

    Am sure there are other ways to test fro empty strings but I find that the xstring package works well for me.

  • The code below treats the first element of the list as number one. If you want that to start from zero the code will require adjustment.

Code:

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


\newcommand*{\GetNthMember}[3]{%
    % #1 = macro to assign value to
    % #2 = list
    % #3 = n
    \edef\List{#2}%
    \edef#1{}%
    \foreach [count=\c] \Member in \List {%
        \IfEq{\c}{#3}{%
            \xdef#1{\Member}%
            \breakforeach%
            %\typeout{****Found Member #3 = #1}%
        }{}%
    }%
}%

\newcommand*{\NodeColor}{}%

\begin{document}
\begin{tikzpicture}[ultra thick]
\def\n{5}
\def\weights{"1","2","3","4","","n"}
\foreach \i  in {0,...,\n}{
    \GetNthMember{\MyLabel}{\weights}{\i}%
    \def\NodeColor{blue}%
    \IfStrEq{\MyLabel}{}{\def\NodeColor{red}}{}%
    \IfStrEq{\MyLabel}{""}{\def\NodeColor{red}}{}%
    \node [shape=rectangle, draw=\NodeColor] at (\i,0) {\strut\MyLabel};
}
\end{tikzpicture}
\end{document}
Peter Grill
  • 223,288
  • Actually, I need to check if the element is empty. For example the fifth element in your list is empty, and I would like to treat it differently. So, how can you check it? – adn Jan 03 '13 at 06:28
  • Updated to include Notes section. Let me know if that makes sense. – Peter Grill Jan 03 '13 at 06:31
  • Ohh.. I see. The thing is that in the pgf array \weights (I don't know the name of that thing) I read that you have to put in quotes the elements that are not numbers, that's the reason for the quotes in the definition. Then, I need to define empty elements, and treat them differently. – adn Jan 03 '13 at 06:41
  • No, you don't need to double quote it. If the string has a comma in it you would need to add an extra brace group. Updated code to test for both a non exist ant entry or a double quoted empty entry. – Peter Grill Jan 03 '13 at 07:08
  • Thanks, the xstring IfStrEq works to test whether the element is empty or not. – adn Jan 03 '13 at 07:37
  • I am a little perplexed as to why this got the answer, compared to my solution below, done in ~10 lines of code. – Nicholas Hamilton Jan 03 '13 at 08:52
1

I think this is a simpler solution:

\documentclass{article}

\usepackage{tikz}
\usepackage{xifthen}

\pagestyle{empty}
\begin{document}
    \begin{tikzpicture}
    \def\wt{1,2,3,4,,6}
    \newcounter{cnt}
    \foreach \x in \wt{
        \addtocounter{cnt}{1}
        \node at (0,\thecnt) {\ifthenelse{\equal{\x}{}}{empty}{\x}};
    }
    \end{tikzpicture}
\end{document}

Output

0

(Just for completeness, using Peter's answer and the pgfmathparse array retrieval method.)

The xstring package works in my case. Using the pgf way of retrieving the elements (don't know if is the best or correct, though), this is the code that does the trick:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{etoolbox}
\usepackage{xstring}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}
\def\n{5}
\def\weights{{"1","2","3","4","","n"}}

\foreach \i [count=\c] in {0,...,\n}{
  \pgfmathparse{\weights[\i]} \let\lbl\pgfmathresult
  \IfStrEq{\lbl}{}{%
    \node at (0,\c) {empty};%
  }{%
    \node at (0,\c) {$l_{\lbl}$};%
  }%
}

\end{tikzpicture}
\end{document}
adn
  • 11,233
  • I would recommend you not redefine existing commands such as \label. Also, was not aware the \pgfmathparse could index into an array, even it seems to be indexing in reverse order. This may not be important, but this does have an issue for an array index out of bounds, where as my solution will return an empty result. – Peter Grill Jan 03 '13 at 17:42
  • Actually, for out of bounds it throws and error. I get the idea somewhere in the manual, but I don't remember where. – adn Jan 04 '13 at 01:19