# Package to test whether a string is in a list

Is there a package that provides a command for testing whether a string is in a list? I saw several answers that define their own commands to perform this or similar tasks, but I prefer a "self-evolving", and well-documented solution for this kind of tasks. More precisely, the command should be something like this

\IfStringInList{string}{list}{DoThisIfTrue}{DoThisIfFalse}


For instance

\IfStringInList{Paul}{George,John,Paul,Ringo}{Beat it}{Roll it}


EDIT: I'm not against defining commands. I expected thas this natural functionality was present in a ready-to-use package, that can be accessed in a very simple way.

• Is "list" always going to be defined as a comma-separated collection of strings? – Mico Aug 11 '15 at 16:20
• Probably. I think it is somehow natural, while {}{}{}..., for instance, is not. – ASdeL Aug 11 '15 at 16:29
• you don't need a package \in@ and \ifin@ are predefined in the latex format. – David Carlisle Aug 11 '15 at 16:36
• @David: Thanks. This is interesting. Should I use makeatletter/makeatother?. I would like a plain simple command. – ASdeL Aug 11 '15 at 16:49
• @ASdeL you need something to access commands with @ but see Heiko's answer which is the same as mine (which I have now deleted) but just packaged for actual use. – David Carlisle Aug 11 '15 at 16:54

The xtring package provides such command:

\documentclass{article}
\usepackage{xstring}
\newcommand\IfStringInList[2]{\IfSubStr{,#2,}{,#1,}}
\begin{document}
\IfStringInList{Paul}{George,John,Paul,Ringo}{True}{False}

\IfStringInList{Joe}{George,John,Paul,Ringo}{True}{False}

\IfStringInList{ul,Ri}{George,John,Paul,Ringo}{True}{False}
\end{document}

• I'm not convinced with this. I do not like that \IfSubStr{George,John,Paul,Ringo}{ul,Ri}{True}{False} is True. – ASdeL Aug 11 '15 at 16:17
• Good recovery. +1 – Steven B. Segletes Aug 11 '15 at 18:46

Simple LaTeX with the kernel command \in@:

\documentclass{article}

\makeatletter
\newcommand*{\IfStringInList}[2]{%
\in@{,#1,}{,#2,}%
\ifin@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother

\begin{document}
\IfStringInList{Paul}{George,John,Paul,Ringo}{Beat it}{Roll it}
\end{document}


## Manual solution without defining a command and without \makeatletter

As requested by the comment. I do not see a sense, not to define a macro.

\csname in@\endcsname{,Paul,}{,George,John,Paul,Ringo,}%
\expandafter\ifx\csname ifin@\expandafter\endcsname\csname iftrue\endcsname
Beat it%
\else
Roll it%
\fi


}

The lengthy replacement for \ifin@ is needed, when this construct is inside another \if branch.

• Odd I didn't see this but system says you posted a minute ahead of me, I'll delete mine:-) – David Carlisle Aug 11 '15 at 16:52
• @Heiko: Nice answer, but you are still defining your own command. Off course, the command can be removed, but then makeat... must be used between begin/end{document}. – ASdeL Aug 11 '15 at 17:13
• @ASdeL what's to say against defining a command? (If you insist you can put the code in a package of your own and – voila – you have a package which provides the command that you want…) – clemens Aug 11 '15 at 17:20
• @clemens: See my edit in the question. Thanks. – ASdeL Aug 11 '15 at 21:35

expl3 has this ready for use: \clist_if_in:nnTF {<clist>} {<item>} {<true>} {<false>}:

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand \IfStringInList {mmmm}
{ \clist_if_in:nnTF {#2} {#1} {#3} {#4} }
\ExplSyntaxOff
\begin{document}
\IfStringInList{Paul}{George,John,Paul,Ringo}{Beat it}{Roll it}% Beat it

\IfStringInList{ul,Ri}{George,John,Paul,Ringo}{Beat it}{Roll it}% Roll it
\end{document}


Here's a LuaLaTeX-based solution. It sets up a macro called \IfStringInList and implements it via a call to the Lua function string.find to set up "true" and "false" branches. Observe that both the target string and the search string can be quite general; in particular, the target string need not be a comma-separated collection of strings.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for "\luastring" macro
\newcommand\IfStringInList[4]{%
\directlua{if string.find(\luastring{#2},\luastring{#1}) then
tex.print(\luastring{#3})
else
tex.print(\luastring{#4})
end}%
}
\begin{document}
\IfStringInList{Paul}{George,John,Paul,Ringo}{Beat it}{Roll it}% "Beat it"

\IfStringInList{Mozart}{GeorgeJohnPaulRingo}{Strum It}{Hum it} % "Hum it"

\IfStringInList{George,John,Paul,Ringo}{ul,Ri}{True}{False}    % "False"
\end{document}

• Thank you, but I am looking for an already defined command \IfStringInList (or any other name) in a common package. – ASdeL Aug 11 '15 at 16:34

Another way... EDITED to allow blank fields (A,,B)

\documentclass{article}
\usepackage{ifthen}
\newcommand\IfStringInList[4]{\stringsearch#1:#2,\relax\relax%
\if T\found#3\else#4\fi}
\def\stringsearch#1:#2,#3\relax{\ifthenelse{\equal{#1}{#2}}{\def\found{T}}{%
\if\relax#3\relax\def\found{F}\else\stringsearch #1:#3\relax\fi}}
\begin{document}
\IfStringInList{Paul}{George,John,Paul,Ringo}{Beat it}{Roll it}

\IfStringInList{Paul}{George,,John,Paul,Ringo}{Beat it}{Roll it}

\IfStringInList{Yanni}{George,John,Paul,Ringo}{Beat it}{Roll it}
\end{document}

• Thank you, but I am looking for an already defined command \IfStringInList (or any other name) in a common package. – ASdeL Aug 11 '15 at 16:42