我希望有两个不同的列表:
\listone{a,b,c}
\listtwo{a,c,d,e}
并有两个宏:
\iflistincludedAND{lista}{listb}{<true>}{<false>}
如果 lista 中的每个项目都包含在 listb 中,则返回 true
和
\iflistincludedOR{lista}{listb}{<true>}{<false>}
true
如果 lista 中至少有一个项目包含在 listb 中,则返回该结果。
是否有人足够聪明且善良,能够帮助我实现这一目标?
非常感谢!
答案1
稍微玩一下etoolbox
和\ifinlist
布尔\forcsvlist
值:
\documentclass{article}
\usepackage{etoolbox}
\newcommand*\listone{}
\newcommand*\listtwo{}
\newcommand*\listthree{}
\forcsvlist{\listadd\listone}{a,b,c}
\forcsvlist{\listadd\listtwo}{a,c,d,e}
\forcsvlist{\listadd\listthree}{d,e}
\makeatletter
% a version of \ifinlist which takes the item as last argument so we can use
% it as handler in \forcsvlist
\newcommand\my@ifinlist[4]{\ifinlist{#4}{#1}{#2}{#3}}
% a temporary boolean:
\newbool{my@tmp@bool}
\newrobustcmd\iflistincludedAND[2]{%
\booltrue{my@tmp@bool}%
\forlistloop{\my@ifinlist{#2}{}{\boolfalse{my@tmp@bool}}}{#1}%
\ifbool{my@tmp@bool}%
}
\newrobustcmd\iflistincludedOR[2]{%
\boolfalse{my@tmp@bool}%
\forlistloop{\my@ifinlist{#2}{\booltrue{my@tmp@bool}}{}}{#1}%
\ifbool{my@tmp@bool}%
}
\makeatother
\begin{document}
\iflistincludedOR\listone\listtwo{true}{false} % true
\iflistincludedAND\listone\listtwo{true}{false} % false
\iflistincludedOR\listthree\listtwo{true}{false} % true
\iflistincludedAND\listthree\listtwo{true}{false} % true
\iflistincludedOR\listthree\listone{true}{false} % false
\iflistincludedAND\listthree\listone{true}{false} % false
\bigskip
\iflistincludedOR\listtwo\listone{true}{false} % true
\iflistincludedAND\listtwo\listone{true}{false} % false
\iflistincludedOR\listtwo\listthree{true}{false} % true
\iflistincludedAND\listtwo\listthree{true}{false} % false
\iflistincludedOR\listone\listthree{true}{false} % false
\iflistincludedAND\listone\listthree{true}{false} % false
\end{document}
答案2
不是一个etoolbox
版本,而是使用clist
来自的变量expl3
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\NewList}{m}{%
\clist_new:c {l_oliver_#1_clist}
\expandafter\newcommand\csname #1\endcsname{l_oliver_#1_clist}
}
\NewDocumentCommand{\AddToList}{mm}{%
\clist_put_right:cn {#1} {#2}
}
\bool_new:N \l_oliver_lists_equal_bool
\NewDocumentCommand{\iflistincludedAND}{mm+m+m}{
\int_compare:nNnTF { \clist_count:c {#1} } = { \clist_count:c {#2} } {%
\clist_map_inline:cn {#1} {
\bool_set_false:N \l_oliver_lists_equal_bool
\clist_if_in:cnTF {#2} { ##1 }{\bool_gset_true:N \l_oliver_lists_equal_bool}{ %
\clist_map_break:N % Break the list
}%
}% End of inline
\bool_if:nTF {\l_oliver_lists_equal_bool} {#3} { #4 }
}{#4 }
}
\NewDocumentCommand{\iflistincludedOR}{mm+m+m}{%
\bool_set_false:N \l_oliver_lists_equal_bool
\clist_map_inline:cn {#1} {
\bool_set_false:N \l_oliver_lists_equal_bool
\clist_if_in:cnT {#2} { ##1 }{\bool_gset_true:N \l_oliver_lists_equal_bool
}
}% End of inline
\bool_if:nTF {\l_oliver_lists_equal_bool} {#3} { #4 }
}
\ExplSyntaxOff
\begin{document}
\NewList{listone}
\AddToList{\listone}{a,b,c}
\NewList{listtwo}
\AddToList{\listtwo}{a,b,c,d}
\NewList{listthree}
\AddToList{\listthree}{e,f,g}
\iflistincludedAND{\listone}{\listtwo}{Yes - equal!}{Nope, not equal}
\iflistincludedOR{\listone}{\listtwo}{Yes, has one of it}{Nope, not a single one is in it}
\iflistincludedOR{\listone}{\listthree}{Yes, has one of it}{Nope, not a single one is in it}
\end{document}
答案3
xparse
以下是使用和的实现expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\definelist}{mm}
{
\vogel_list_define:nn { #1 } { #2 }
}
\NewDocumentCommand{\iflistincludedAND}{mmmm}
{
\vogel_list_include_and:nnnn { #1 } { #2 } { #3 } { #4 }
}
\NewDocumentCommand{\iflistincludedOR}{mmmm}
{
\vogel_list_include_or:nnnn { #1 } { #2 } { #3 } { #4 }
}
\bool_new:N \l_vogel_list_include_bool
\cs_new_protected:Nn \vogel_list_define:nn
{
\clist_clear_new:c { l_vogel_list_#1_clist }
\clist_set:cn { l_vogel_list_#1_clist } { #2 }
}
\cs_new_protected:Nn \vogel_list_include_or:nnnn
{
\bool_set_false:N \l_vogel_list_include_bool
\clist_map_inline:cn { l_vogel_list_#1_clist }
{
\clist_if_in:cnT { l_vogel_list_#2_clist } { ##1 }
{
\clist_map_break:n { \bool_set_true:N \l_vogel_list_include_bool }
}
}
\bool_if:NTF \l_vogel_list_include_bool { #3 } { #4 }
}
\cs_new_protected:Nn \vogel_list_include_and:nnnn
{
\bool_set_true:N \l_vogel_list_include_bool
\clist_map_inline:cn { l_vogel_list_#1_clist }
{
\clist_if_in:cnF { l_vogel_list_#2_clist } { ##1 }
{
\clist_map_break:n { \bool_set_false:N \l_vogel_list_include_bool }
}
}
\bool_if:NTF \l_vogel_list_include_bool { #3 } { #4 }
}
\ExplSyntaxOff
\begin{document}
\definelist{one}{a,b,c}
\definelist{two}{a,b,c,d}
\definelist{three}{a,b}
\definelist{four}{A,B}
\iflistincludedAND{one}{two}{TRUE}{FALSE}, should be TRUE
\iflistincludedAND{one}{three}{TRUE}{FALSE}, should be FALSE
\iflistincludedOR{one}{three}{TRUE}{FALSE}, should be TRUE
\iflistincludedOR{one}{four}{TRUE}{FALSE}, should be FALSE
\end{document}