Etoolbox:如何比较两个列表?

Etoolbox:如何比较两个列表?

我希望有两个不同的列表:

\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}

在此处输入图片描述

相关内容