Checking if an integer is a member of an integer listMembership checking inside fpevalLaTeX for loop @forPackage to test whether a string is in a listIssue with Expansions of Nested MacrosFast membership test for integer lists/setsCan I defend against “Dimension too large” errors?Definition-time expansiton of command line inputConversion of a String to Integerhow to select a character (or word) from a listChecking if a variable is not nullDefine an expandable function for comparing a token list to a string in LaTeX3Replacing an id (integer) with a string?Integer and floating point accuracy in LaTeX3Unsigned integer variable in a regexpgfkey as integer for ifnumStringify input - string on token listMembership checking inside fpevalConversion of a String to Integer

Why should I "believe in" weak solutions to PDEs?

Does the length of a password for Wi-Fi affect speed?

Getting an entry level IT position later in life

Why is Chromosome 1 called Chromosome 1?

Does a 4 bladed prop have almost twice the thrust of a 2 bladed prop?

How do I get the =LEFT function in excel, to also take the number zero as the first number?

Does this put me at risk for identity theft?

Is a switch from R to Python worth it?

Generate a random point outside a given rectangle within a map

How to continue a line in Latex in math mode?

Print only the last three columns from file

Is this cheap "air conditioner" able to cool a room?

Secure my password from unsafe servers

What is an air conditioner compressor hard start kit and how does it work?

I was contacted by a private bank overseas to get my inheritance

Is DC heating faster than AC heating?

Using command line how to open a specific section of GUI System Preferences?

Best way to explain to my boss that I cannot attend a team summit because it is on Rosh Hashana or any other Jewish Holiday

How would a family travel from Indiana to Texas in 1911?

What can make Linux so unresponsive?

Can I enter a rental property without giving notice if I'm afraid a tenant may be hurt?

Pronouns when writing from the point of view of a robot

Can ads on a page read my password?

Can you use the Help action to give a 2019 UA Artillerist artificer's turret advantage?



Checking if an integer is a member of an integer list


Membership checking inside fpevalLaTeX for loop @forPackage to test whether a string is in a listIssue with Expansions of Nested MacrosFast membership test for integer lists/setsCan I defend against “Dimension too large” errors?Definition-time expansiton of command line inputConversion of a String to Integerhow to select a character (or word) from a listChecking if a variable is not nullDefine an expandable function for comparing a token list to a string in LaTeX3Replacing an id (integer) with a string?Integer and floating point accuracy in LaTeX3Unsigned integer variable in a regexpgfkey as integer for ifnumStringify input - string on token listMembership checking inside fpevalConversion of a String to Integer






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








6















Is there any way to check whether an integer is a member of a list of integer numbers and return a boolean?



I found this neat solution, here that does a great job. It checks whether a string exists in a list of strings:




documentclassarticle
usepackagexstring
newcommandIfStringInList[2]IfSubStr,#2,,#1,
begindocument
IfStringInListPaulGeorge,John,Paul,RingoTrueFalse
enddocument



However, it does return a string not a boolean "true" or "false" and caused me some difficulty which is posted here.



Let's call the macro I would like to have ISMEMBER. My goal is to use ISMEMBER and examine whether an integer is in the list and depending on whether it is or not, perform some tasks, as an example:



fpeval ISMEMBER11,2,3,4,5 ? MACRO_FOR_MEMBERS : MACRO_FOR_NON_MEMBERS 


Is such functionality possible?










share|improve this question





















  • 1





    I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

    – MarcinKonowalczyk
    Jul 27 at 23:11

















6















Is there any way to check whether an integer is a member of a list of integer numbers and return a boolean?



I found this neat solution, here that does a great job. It checks whether a string exists in a list of strings:




documentclassarticle
usepackagexstring
newcommandIfStringInList[2]IfSubStr,#2,,#1,
begindocument
IfStringInListPaulGeorge,John,Paul,RingoTrueFalse
enddocument



However, it does return a string not a boolean "true" or "false" and caused me some difficulty which is posted here.



Let's call the macro I would like to have ISMEMBER. My goal is to use ISMEMBER and examine whether an integer is in the list and depending on whether it is or not, perform some tasks, as an example:



fpeval ISMEMBER11,2,3,4,5 ? MACRO_FOR_MEMBERS : MACRO_FOR_NON_MEMBERS 


Is such functionality possible?










share|improve this question





















  • 1





    I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

    – MarcinKonowalczyk
    Jul 27 at 23:11













6












6








6


1






Is there any way to check whether an integer is a member of a list of integer numbers and return a boolean?



I found this neat solution, here that does a great job. It checks whether a string exists in a list of strings:




documentclassarticle
usepackagexstring
newcommandIfStringInList[2]IfSubStr,#2,,#1,
begindocument
IfStringInListPaulGeorge,John,Paul,RingoTrueFalse
enddocument



However, it does return a string not a boolean "true" or "false" and caused me some difficulty which is posted here.



Let's call the macro I would like to have ISMEMBER. My goal is to use ISMEMBER and examine whether an integer is in the list and depending on whether it is or not, perform some tasks, as an example:



fpeval ISMEMBER11,2,3,4,5 ? MACRO_FOR_MEMBERS : MACRO_FOR_NON_MEMBERS 


Is such functionality possible?










share|improve this question
















Is there any way to check whether an integer is a member of a list of integer numbers and return a boolean?



I found this neat solution, here that does a great job. It checks whether a string exists in a list of strings:




documentclassarticle
usepackagexstring
newcommandIfStringInList[2]IfSubStr,#2,,#1,
begindocument
IfStringInListPaulGeorge,John,Paul,RingoTrueFalse
enddocument



However, it does return a string not a boolean "true" or "false" and caused me some difficulty which is posted here.



Let's call the macro I would like to have ISMEMBER. My goal is to use ISMEMBER and examine whether an integer is in the list and depending on whether it is or not, perform some tasks, as an example:



fpeval ISMEMBER11,2,3,4,5 ? MACRO_FOR_MEMBERS : MACRO_FOR_NON_MEMBERS 


Is such functionality possible?







macros strings comparison number l3fp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 28 at 0:16









Phelype Oleinik

32.4k7 gold badges56 silver badges111 bronze badges




32.4k7 gold badges56 silver badges111 bronze badges










asked Jul 27 at 22:35









AFPAFP

2,4475 gold badges28 silver badges57 bronze badges




2,4475 gold badges28 silver badges57 bronze badges










  • 1





    I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

    – MarcinKonowalczyk
    Jul 27 at 23:11












  • 1





    I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

    – MarcinKonowalczyk
    Jul 27 at 23:11







1




1





I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

– MarcinKonowalczyk
Jul 27 at 23:11





I think an answer to one of my questions might be helpful here: tex.stackexchange.com/a/496671/85504

– MarcinKonowalczyk
Jul 27 at 23:11










2 Answers
2






active

oldest

votes


















10














You can use do a comma-separated list parser to loop through the list of items and check if the given item is present in the list. Since the comma-separated list can be read by using a delimited macro, this can be done expandably, allowing you to plug the macro into fpeval to get the syntax you want.



Using expl3 (you are loading it with xfp anyway) something like this would solve the problem:



ExplSyntaxOn
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF
__afp_ismember_loop:nw #1 #2 , q_recursion_tail , q_recursion_stop
cs_new:Npn __afp_ismember_loop:nw #1#2,

quark_if_recursion_tail_stop_do:nn #2
prg_return_false:
int_compare:nNnTF #1 = #2
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:nw #1

ExplSyntaxOff


The code above defines a conditional afp_int_ismember:nn(TF), whose first argument is the item to check, and the second is the comma-separated list. The macro starts by expanding __afp_ismember_loop:nw: this macro takes the item to be tested (#1) and the first item in the list, delimited by a , (#2). The macro tests the equality of #1 and #2 using int_compare:nNnTF and issues prg_return_true: if they are equal or calls __afp_ismember_loop:nw for the next item. If the end of the list is found (i.e., q_recursion_tail is grabbed), then the function issues prg_return_false: because no match was found for #1.



The code above can be tweaked to replace int_compare:nNnTF by a generic equality comparison function. If you do that you can define wrappers around __afp_ismember_loop:nw to create ismember functions for different data types. The code below does that and defines two functions: afp_int_ismember:nn(TF) (using int_compare:nNnTF) and afp_str_ismember:nn(TF) (using str_if_eq:eeTF). Doing that you can even test if I'm a member of the Beatles!




enter image description here




To use the function in fpeval you just need the predicate form (afp_int_ismember_p:nn) of the conditional function:



fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 


And the string version would also work here:



fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321 



Full code:



documentclassarticle
usepackageexpl3
usepackagexparse
usepackagexfp
ExplSyntaxOn
% Core code for the membership test
cs_new:Npn __afp_ismember_loop:Nnw #1#2#3,

quark_if_recursion_tail_stop_do:nn #3
prg_return_false:
#1 #2 #3
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:Nnw #1 #2

% Wrapper for testing integers
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw __afp_int_isequal:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

prg_new_conditional:Npnn __afp_int_isequal:nn #1#2 p, T, F, TF

int_compare:nNnTF #1 = #2
prg_return_true:
prg_return_false:

% Wrappers for testing strings
% With expansion
prg_new_conditional:Npnn afp_str_ismember:ee #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:eeTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Without expansion
prg_new_conditional:Npnn afp_str_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Sample commands
NewExpandableDocumentCommand IntIsmember m m

afp_int_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

NewExpandableDocumentCommand StrIsmember m m

afp_str_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

ExplSyntaxOff
begindocument
IntIsmember11,2,3

IntIsmember41,2,3

StrIsmemberPaulGeorge,John,Paul,Ringo

textbfStrIsmemberPhelypeGeorge,John,Paul,Ringo

ExplSyntaxOn
fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 par
fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321
ExplSyntaxOff
enddocument





share|improve this answer



























  • That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

    – siracusa
    Jul 28 at 2:28






  • 1





    @siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

    – Phelype Oleinik
    Jul 28 at 2:33












  • @PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

    – frougon
    Jul 28 at 6:28












  • @frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

    – Phelype Oleinik
    Jul 28 at 16:09


















8














Something like this? The macro name is inspired by the Mathematica command MemberQ, and the code comes from here. This solution does not require any packages.



documentclassarticle
newififmember
makeatletter% for @for see e.g. https://tex.stackexchange.com/a/100684/121799
%from https://tex.stackexchange.com/a/498576/121799
newcommandMemberQ[2]globalmemberfalse%
@fornext:=#1doifnumnext=#2globalmembertruefi
makeatother
begindocument

MemberQ1,2,3,42
ifmember 2 is in list fi

MemberQ1,2,3,45
ifmember 5 is in listelse%
5 is not in the listfi
enddocument





share|improve this answer






















  • 4





    Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

    – manooooh
    Jul 28 at 0:05







  • 1





    @manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

    – AFP
    Jul 28 at 0:40







  • 3





    @AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

    – Phelype Oleinik
    Jul 28 at 2:19













Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "85"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f501773%2fchecking-if-an-integer-is-a-member-of-an-integer-list%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









10














You can use do a comma-separated list parser to loop through the list of items and check if the given item is present in the list. Since the comma-separated list can be read by using a delimited macro, this can be done expandably, allowing you to plug the macro into fpeval to get the syntax you want.



Using expl3 (you are loading it with xfp anyway) something like this would solve the problem:



ExplSyntaxOn
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF
__afp_ismember_loop:nw #1 #2 , q_recursion_tail , q_recursion_stop
cs_new:Npn __afp_ismember_loop:nw #1#2,

quark_if_recursion_tail_stop_do:nn #2
prg_return_false:
int_compare:nNnTF #1 = #2
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:nw #1

ExplSyntaxOff


The code above defines a conditional afp_int_ismember:nn(TF), whose first argument is the item to check, and the second is the comma-separated list. The macro starts by expanding __afp_ismember_loop:nw: this macro takes the item to be tested (#1) and the first item in the list, delimited by a , (#2). The macro tests the equality of #1 and #2 using int_compare:nNnTF and issues prg_return_true: if they are equal or calls __afp_ismember_loop:nw for the next item. If the end of the list is found (i.e., q_recursion_tail is grabbed), then the function issues prg_return_false: because no match was found for #1.



The code above can be tweaked to replace int_compare:nNnTF by a generic equality comparison function. If you do that you can define wrappers around __afp_ismember_loop:nw to create ismember functions for different data types. The code below does that and defines two functions: afp_int_ismember:nn(TF) (using int_compare:nNnTF) and afp_str_ismember:nn(TF) (using str_if_eq:eeTF). Doing that you can even test if I'm a member of the Beatles!




enter image description here




To use the function in fpeval you just need the predicate form (afp_int_ismember_p:nn) of the conditional function:



fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 


And the string version would also work here:



fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321 



Full code:



documentclassarticle
usepackageexpl3
usepackagexparse
usepackagexfp
ExplSyntaxOn
% Core code for the membership test
cs_new:Npn __afp_ismember_loop:Nnw #1#2#3,

quark_if_recursion_tail_stop_do:nn #3
prg_return_false:
#1 #2 #3
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:Nnw #1 #2

% Wrapper for testing integers
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw __afp_int_isequal:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

prg_new_conditional:Npnn __afp_int_isequal:nn #1#2 p, T, F, TF

int_compare:nNnTF #1 = #2
prg_return_true:
prg_return_false:

% Wrappers for testing strings
% With expansion
prg_new_conditional:Npnn afp_str_ismember:ee #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:eeTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Without expansion
prg_new_conditional:Npnn afp_str_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Sample commands
NewExpandableDocumentCommand IntIsmember m m

afp_int_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

NewExpandableDocumentCommand StrIsmember m m

afp_str_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

ExplSyntaxOff
begindocument
IntIsmember11,2,3

IntIsmember41,2,3

StrIsmemberPaulGeorge,John,Paul,Ringo

textbfStrIsmemberPhelypeGeorge,John,Paul,Ringo

ExplSyntaxOn
fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 par
fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321
ExplSyntaxOff
enddocument





share|improve this answer



























  • That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

    – siracusa
    Jul 28 at 2:28






  • 1





    @siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

    – Phelype Oleinik
    Jul 28 at 2:33












  • @PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

    – frougon
    Jul 28 at 6:28












  • @frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

    – Phelype Oleinik
    Jul 28 at 16:09















10














You can use do a comma-separated list parser to loop through the list of items and check if the given item is present in the list. Since the comma-separated list can be read by using a delimited macro, this can be done expandably, allowing you to plug the macro into fpeval to get the syntax you want.



Using expl3 (you are loading it with xfp anyway) something like this would solve the problem:



ExplSyntaxOn
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF
__afp_ismember_loop:nw #1 #2 , q_recursion_tail , q_recursion_stop
cs_new:Npn __afp_ismember_loop:nw #1#2,

quark_if_recursion_tail_stop_do:nn #2
prg_return_false:
int_compare:nNnTF #1 = #2
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:nw #1

ExplSyntaxOff


The code above defines a conditional afp_int_ismember:nn(TF), whose first argument is the item to check, and the second is the comma-separated list. The macro starts by expanding __afp_ismember_loop:nw: this macro takes the item to be tested (#1) and the first item in the list, delimited by a , (#2). The macro tests the equality of #1 and #2 using int_compare:nNnTF and issues prg_return_true: if they are equal or calls __afp_ismember_loop:nw for the next item. If the end of the list is found (i.e., q_recursion_tail is grabbed), then the function issues prg_return_false: because no match was found for #1.



The code above can be tweaked to replace int_compare:nNnTF by a generic equality comparison function. If you do that you can define wrappers around __afp_ismember_loop:nw to create ismember functions for different data types. The code below does that and defines two functions: afp_int_ismember:nn(TF) (using int_compare:nNnTF) and afp_str_ismember:nn(TF) (using str_if_eq:eeTF). Doing that you can even test if I'm a member of the Beatles!




enter image description here




To use the function in fpeval you just need the predicate form (afp_int_ismember_p:nn) of the conditional function:



fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 


And the string version would also work here:



fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321 



Full code:



documentclassarticle
usepackageexpl3
usepackagexparse
usepackagexfp
ExplSyntaxOn
% Core code for the membership test
cs_new:Npn __afp_ismember_loop:Nnw #1#2#3,

quark_if_recursion_tail_stop_do:nn #3
prg_return_false:
#1 #2 #3
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:Nnw #1 #2

% Wrapper for testing integers
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw __afp_int_isequal:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

prg_new_conditional:Npnn __afp_int_isequal:nn #1#2 p, T, F, TF

int_compare:nNnTF #1 = #2
prg_return_true:
prg_return_false:

% Wrappers for testing strings
% With expansion
prg_new_conditional:Npnn afp_str_ismember:ee #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:eeTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Without expansion
prg_new_conditional:Npnn afp_str_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Sample commands
NewExpandableDocumentCommand IntIsmember m m

afp_int_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

NewExpandableDocumentCommand StrIsmember m m

afp_str_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

ExplSyntaxOff
begindocument
IntIsmember11,2,3

IntIsmember41,2,3

StrIsmemberPaulGeorge,John,Paul,Ringo

textbfStrIsmemberPhelypeGeorge,John,Paul,Ringo

ExplSyntaxOn
fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 par
fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321
ExplSyntaxOff
enddocument





share|improve this answer



























  • That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

    – siracusa
    Jul 28 at 2:28






  • 1





    @siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

    – Phelype Oleinik
    Jul 28 at 2:33












  • @PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

    – frougon
    Jul 28 at 6:28












  • @frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

    – Phelype Oleinik
    Jul 28 at 16:09













10












10








10







You can use do a comma-separated list parser to loop through the list of items and check if the given item is present in the list. Since the comma-separated list can be read by using a delimited macro, this can be done expandably, allowing you to plug the macro into fpeval to get the syntax you want.



Using expl3 (you are loading it with xfp anyway) something like this would solve the problem:



ExplSyntaxOn
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF
__afp_ismember_loop:nw #1 #2 , q_recursion_tail , q_recursion_stop
cs_new:Npn __afp_ismember_loop:nw #1#2,

quark_if_recursion_tail_stop_do:nn #2
prg_return_false:
int_compare:nNnTF #1 = #2
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:nw #1

ExplSyntaxOff


The code above defines a conditional afp_int_ismember:nn(TF), whose first argument is the item to check, and the second is the comma-separated list. The macro starts by expanding __afp_ismember_loop:nw: this macro takes the item to be tested (#1) and the first item in the list, delimited by a , (#2). The macro tests the equality of #1 and #2 using int_compare:nNnTF and issues prg_return_true: if they are equal or calls __afp_ismember_loop:nw for the next item. If the end of the list is found (i.e., q_recursion_tail is grabbed), then the function issues prg_return_false: because no match was found for #1.



The code above can be tweaked to replace int_compare:nNnTF by a generic equality comparison function. If you do that you can define wrappers around __afp_ismember_loop:nw to create ismember functions for different data types. The code below does that and defines two functions: afp_int_ismember:nn(TF) (using int_compare:nNnTF) and afp_str_ismember:nn(TF) (using str_if_eq:eeTF). Doing that you can even test if I'm a member of the Beatles!




enter image description here




To use the function in fpeval you just need the predicate form (afp_int_ismember_p:nn) of the conditional function:



fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 


And the string version would also work here:



fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321 



Full code:



documentclassarticle
usepackageexpl3
usepackagexparse
usepackagexfp
ExplSyntaxOn
% Core code for the membership test
cs_new:Npn __afp_ismember_loop:Nnw #1#2#3,

quark_if_recursion_tail_stop_do:nn #3
prg_return_false:
#1 #2 #3
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:Nnw #1 #2

% Wrapper for testing integers
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw __afp_int_isequal:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

prg_new_conditional:Npnn __afp_int_isequal:nn #1#2 p, T, F, TF

int_compare:nNnTF #1 = #2
prg_return_true:
prg_return_false:

% Wrappers for testing strings
% With expansion
prg_new_conditional:Npnn afp_str_ismember:ee #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:eeTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Without expansion
prg_new_conditional:Npnn afp_str_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Sample commands
NewExpandableDocumentCommand IntIsmember m m

afp_int_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

NewExpandableDocumentCommand StrIsmember m m

afp_str_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

ExplSyntaxOff
begindocument
IntIsmember11,2,3

IntIsmember41,2,3

StrIsmemberPaulGeorge,John,Paul,Ringo

textbfStrIsmemberPhelypeGeorge,John,Paul,Ringo

ExplSyntaxOn
fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 par
fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321
ExplSyntaxOff
enddocument





share|improve this answer















You can use do a comma-separated list parser to loop through the list of items and check if the given item is present in the list. Since the comma-separated list can be read by using a delimited macro, this can be done expandably, allowing you to plug the macro into fpeval to get the syntax you want.



Using expl3 (you are loading it with xfp anyway) something like this would solve the problem:



ExplSyntaxOn
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF
__afp_ismember_loop:nw #1 #2 , q_recursion_tail , q_recursion_stop
cs_new:Npn __afp_ismember_loop:nw #1#2,

quark_if_recursion_tail_stop_do:nn #2
prg_return_false:
int_compare:nNnTF #1 = #2
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:nw #1

ExplSyntaxOff


The code above defines a conditional afp_int_ismember:nn(TF), whose first argument is the item to check, and the second is the comma-separated list. The macro starts by expanding __afp_ismember_loop:nw: this macro takes the item to be tested (#1) and the first item in the list, delimited by a , (#2). The macro tests the equality of #1 and #2 using int_compare:nNnTF and issues prg_return_true: if they are equal or calls __afp_ismember_loop:nw for the next item. If the end of the list is found (i.e., q_recursion_tail is grabbed), then the function issues prg_return_false: because no match was found for #1.



The code above can be tweaked to replace int_compare:nNnTF by a generic equality comparison function. If you do that you can define wrappers around __afp_ismember_loop:nw to create ismember functions for different data types. The code below does that and defines two functions: afp_int_ismember:nn(TF) (using int_compare:nNnTF) and afp_str_ismember:nn(TF) (using str_if_eq:eeTF). Doing that you can even test if I'm a member of the Beatles!




enter image description here




To use the function in fpeval you just need the predicate form (afp_int_ismember_p:nn) of the conditional function:



fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 


And the string version would also work here:



fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321 



Full code:



documentclassarticle
usepackageexpl3
usepackagexparse
usepackagexfp
ExplSyntaxOn
% Core code for the membership test
cs_new:Npn __afp_ismember_loop:Nnw #1#2#3,

quark_if_recursion_tail_stop_do:nn #3
prg_return_false:
#1 #2 #3
use_i_delimit_by_q_recursion_stop:nw prg_return_true:
__afp_ismember_loop:Nnw #1 #2

% Wrapper for testing integers
prg_new_conditional:Npnn afp_int_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw __afp_int_isequal:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

prg_new_conditional:Npnn __afp_int_isequal:nn #1#2 p, T, F, TF

int_compare:nNnTF #1 = #2
prg_return_true:
prg_return_false:

% Wrappers for testing strings
% With expansion
prg_new_conditional:Npnn afp_str_ismember:ee #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:eeTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Without expansion
prg_new_conditional:Npnn afp_str_ismember:nn #1#2 p, T, F, TF

__afp_ismember_loop:Nnw str_if_eq:nnTF #1 #2 ,
q_recursion_tail , q_recursion_stop

% Sample commands
NewExpandableDocumentCommand IntIsmember m m

afp_int_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

NewExpandableDocumentCommand StrIsmember m m

afp_str_ismember:nnTF #1 #2
#1~is~member~of~`#2'
#1~is~emphnot~member~of~`#2'

ExplSyntaxOff
begindocument
IntIsmember11,2,3

IntIsmember41,2,3

StrIsmemberPaulGeorge,John,Paul,Ringo

textbfStrIsmemberPhelypeGeorge,John,Paul,Ringo

ExplSyntaxOn
fpeval afp_int_ismember_p:nn 1 1,2,3,4,5 ? 123 : 321 par
fpeval afp_str_ismember_p:nn Phelype George,John,Paul,Ringo ? 123 : 321
ExplSyntaxOff
enddocument






share|improve this answer














share|improve this answer



share|improve this answer








edited Jul 28 at 23:03

























answered Jul 28 at 0:15









Phelype OleinikPhelype Oleinik

32.4k7 gold badges56 silver badges111 bronze badges




32.4k7 gold badges56 silver badges111 bronze badges















  • That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

    – siracusa
    Jul 28 at 2:28






  • 1





    @siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

    – Phelype Oleinik
    Jul 28 at 2:33












  • @PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

    – frougon
    Jul 28 at 6:28












  • @frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

    – Phelype Oleinik
    Jul 28 at 16:09

















  • That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

    – siracusa
    Jul 28 at 2:28






  • 1





    @siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

    – Phelype Oleinik
    Jul 28 at 2:33












  • @PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

    – frougon
    Jul 28 at 6:28












  • @frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

    – Phelype Oleinik
    Jul 28 at 16:09
















That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

– siracusa
Jul 28 at 2:28





That answer makes me wonder why there isn't an expandable clist_if_in:nn(TF)

– siracusa
Jul 28 at 2:28




1




1





@siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

– Phelype Oleinik
Jul 28 at 2:33






@siracusa There could be... Please, do ask :-) The only problem I see is that we would possibly need a clist_str_if_in:nn(TF) and a clist_tl_if_in:nn(TF) (and potentially others) because the only clisty thing here is that the function looks up something in a clist: the actual data type in the clist var would need to be queried... Perhaps str_if_in_clist:nn and tl_if_in_clist:nn and int_if_in_clist:nn...

– Phelype Oleinik
Jul 28 at 2:33














@PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

– frougon
Jul 28 at 6:28






@PhelypeOleinik Very nice! Any reason you use cs_new:Npn instead of NewExpandableDocumentCommand for the document-level commands? Is it that you don't want to load xparse, maybe? Or... are you a rebel? :)

– frougon
Jul 28 at 6:28














@frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

– Phelype Oleinik
Jul 28 at 16:09





@frougon A rebel, probably ;-) Actually I didn't even think of it: the IntIsmember and StrIsmember commands are just examples. But you're right, xparse is better here. Thanks :-)

– Phelype Oleinik
Jul 28 at 16:09













8














Something like this? The macro name is inspired by the Mathematica command MemberQ, and the code comes from here. This solution does not require any packages.



documentclassarticle
newififmember
makeatletter% for @for see e.g. https://tex.stackexchange.com/a/100684/121799
%from https://tex.stackexchange.com/a/498576/121799
newcommandMemberQ[2]globalmemberfalse%
@fornext:=#1doifnumnext=#2globalmembertruefi
makeatother
begindocument

MemberQ1,2,3,42
ifmember 2 is in list fi

MemberQ1,2,3,45
ifmember 5 is in listelse%
5 is not in the listfi
enddocument





share|improve this answer






















  • 4





    Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

    – manooooh
    Jul 28 at 0:05







  • 1





    @manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

    – AFP
    Jul 28 at 0:40







  • 3





    @AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

    – Phelype Oleinik
    Jul 28 at 2:19















8














Something like this? The macro name is inspired by the Mathematica command MemberQ, and the code comes from here. This solution does not require any packages.



documentclassarticle
newififmember
makeatletter% for @for see e.g. https://tex.stackexchange.com/a/100684/121799
%from https://tex.stackexchange.com/a/498576/121799
newcommandMemberQ[2]globalmemberfalse%
@fornext:=#1doifnumnext=#2globalmembertruefi
makeatother
begindocument

MemberQ1,2,3,42
ifmember 2 is in list fi

MemberQ1,2,3,45
ifmember 5 is in listelse%
5 is not in the listfi
enddocument





share|improve this answer






















  • 4





    Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

    – manooooh
    Jul 28 at 0:05







  • 1





    @manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

    – AFP
    Jul 28 at 0:40







  • 3





    @AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

    – Phelype Oleinik
    Jul 28 at 2:19













8












8








8







Something like this? The macro name is inspired by the Mathematica command MemberQ, and the code comes from here. This solution does not require any packages.



documentclassarticle
newififmember
makeatletter% for @for see e.g. https://tex.stackexchange.com/a/100684/121799
%from https://tex.stackexchange.com/a/498576/121799
newcommandMemberQ[2]globalmemberfalse%
@fornext:=#1doifnumnext=#2globalmembertruefi
makeatother
begindocument

MemberQ1,2,3,42
ifmember 2 is in list fi

MemberQ1,2,3,45
ifmember 5 is in listelse%
5 is not in the listfi
enddocument





share|improve this answer















Something like this? The macro name is inspired by the Mathematica command MemberQ, and the code comes from here. This solution does not require any packages.



documentclassarticle
newififmember
makeatletter% for @for see e.g. https://tex.stackexchange.com/a/100684/121799
%from https://tex.stackexchange.com/a/498576/121799
newcommandMemberQ[2]globalmemberfalse%
@fornext:=#1doifnumnext=#2globalmembertruefi
makeatother
begindocument

MemberQ1,2,3,42
ifmember 2 is in list fi

MemberQ1,2,3,45
ifmember 5 is in listelse%
5 is not in the listfi
enddocument






share|improve this answer














share|improve this answer



share|improve this answer








edited Jul 28 at 0:01

























answered Jul 27 at 23:56









user121799user121799

126k6 gold badges192 silver badges357 bronze badges




126k6 gold badges192 silver badges357 bronze badges










  • 4





    Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

    – manooooh
    Jul 28 at 0:05







  • 1





    @manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

    – AFP
    Jul 28 at 0:40







  • 3





    @AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

    – Phelype Oleinik
    Jul 28 at 2:19












  • 4





    Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

    – manooooh
    Jul 28 at 0:05







  • 1





    @manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

    – AFP
    Jul 28 at 0:40







  • 3





    @AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

    – Phelype Oleinik
    Jul 28 at 2:19







4




4





Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

– manooooh
Jul 28 at 0:05






Oh, an answer of @marmot that does not include anything from TikZ!?! I MUST READ IT.

– manooooh
Jul 28 at 0:05





1




1





@manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

– AFP
Jul 28 at 0:40






@manooooh This is a great solution and also compact. I wish I could select two accepted answers. Can this be used inside a fpeval? Thanks for your time.

– AFP
Jul 28 at 0:40





3




3





@AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

– Phelype Oleinik
Jul 28 at 2:19





@AFP No, it cannot because it isn't expandable (@for isn't expandable because it does assignments, and membertrue and memberfalse are also assignments, so not expandable). The expandability of l3fp allows you to use it virtually anywhere TeX expects a number (see this trick, for example). The downside of this expandability is that everything inside an expression must be expandable too.

– Phelype Oleinik
Jul 28 at 2:19

















draft saved

draft discarded
















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f501773%2fchecking-if-an-integer-is-a-member-of-an-integer-list%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form