如何概括这宏使其打印字符串出现的次数并允许任意分隔符(包括空格)?谢谢。
输出结果可能是:
如果为 FALSE,则为 0;如果为 TRUE,则为 1,2,3... 发生的次数。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\ifmember}{mmmm}
{
\clist_if_in:onTF { #2 } { #1 } { #3 } { #4 }
}
\cs_generate_variant:Nn \clist_if_in:nnTF { o }
\ExplSyntaxOff
\begin{document}
\ifmember{3}{3,4}{True}{False} (expected: True)
\ifmember{3}{ 3 ,4}{True}{False} (expected: True)
\newcommand{\foo}{3,4}
\ifmember{3}{\foo}{True}{False} (expected: True)
\renewcommand{\foo}{3, 4}
\ifmember{4}{\foo}{True}{False} (expected: True)
\ifmember{foo}{\foo}{True}{False} (expected: False)
\end{document}
答案1
您可以映射列表并根据给定的标记列表检查每个项目,如果匹配则增加计数器。最后,打印计数器的值。
分隔符(默认为逗号)在可选参数中指定。
\documentclass{article}
%\usepackage{xparse} % no longer needed
\ExplSyntaxOn
\NewDocumentCommand{\countmember}{O{,}mm}
{
\krantz_countmember:onn { #3 } { #2 } { #1 }
}
\seq_new:N \l__krantz_countmember_items_seq
\int_new:N \l__krantz_countmember_count_int
\cs_new_protected:Nn \krantz_countmember:nnn
{
\int_zero:N \l__krantz_countmember_count_int
\seq_set_split:Nnn \l__krantz_countmember_items_seq { #3 } { #1 }
\seq_map_inline:Nn \l__krantz_countmember_items_seq
{
\tl_if_eq:nnT { ##1 } { #2 } { \int_incr:N \l__krantz_countmember_count_int }
}
\int_to_arabic:n { \l__krantz_countmember_count_int }
}
\cs_generate_variant:Nn \krantz_countmember:nnn { o }
\ExplSyntaxOff
\begin{document}
\countmember{3}{3,4} (expected: 1)
\countmember{3}{ 3 ,4} (expected: 1)
\newcommand{\foo}{3,4}
\countmember{3}{\foo} (expected: 1)
\renewcommand{\foo}{3, 4, 4}
\countmember{4}{\foo} (expected: 2)
\countmember{foo}{\foo} (expected: 0)
\countmember[\\]{1}{1 \\ 2 \\ 1 \\ 0} (expected: 2)
\countmember[ ]{2}{1 2 1 0} (expected: 1)
\renewcommand{\foo}{1 2 1 0}
\countmember[ ]{2}{\foo} (expected: 1)
\end{document}
可以添加一个尾随可选参数,该参数应该是一个控制序列,结果将存储在其中以供以后使用。
\documentclass{article}
%\usepackage{xparse} % no longer needed
\ExplSyntaxOn
\NewDocumentCommand{\countmember}{O{,}mmo}
{
\krantz_countmember:onn { #3 } { #2 } { #1 }
\IfNoValueTF { #4 }
{% just print the count
\int_to_arabic:n { \l__krantz_countmember_count_int }
}
{% store
\tl_clear_new:N #4
\tl_set:Nx #4 { \int_to_arabic:n { \l__krantz_countmember_count_int } }
}
}
\seq_new:N \l__krantz_countmember_items_seq
\int_new:N \l__krantz_countmember_count_int
\cs_new_protected:Nn \krantz_countmember:nnn
{
\int_zero:N \l__krantz_countmember_count_int
\seq_set_split:Nnn \l__krantz_countmember_items_seq { #3 } { #1 }
\seq_map_inline:Nn \l__krantz_countmember_items_seq
{
\tl_if_eq:nnT { ##1 } { #2 } { \int_incr:N \l__krantz_countmember_count_int }
}
}
\cs_generate_variant:Nn \krantz_countmember:nnn { o }
\ExplSyntaxOff
\begin{document}
\countmember{3}{3,4} (expected: 1)
\countmember{3}{ 3 ,4} (expected: 1)
\newcommand{\foo}{3,4}
\countmember{3}{\foo} (expected: 1)
\renewcommand{\foo}{3, 4, 4}
\countmember{4}{\foo} (expected: 2)
\countmember{foo}{\foo} (expected: 0)
\countmember[\\]{1}{1 \\ 2 \\ 1 \\ 0} (expected: 2)
\countmember[ ]{2}{1 2 1 0} (expected: 1)
\renewcommand{\foo}{1 2 1 0}
\countmember[ ]{2}{\foo} (expected: 1)
% store in \foo
\countmember{1}{1,2,2,1,1,2}[\foo]
\foo
\end{document}
输出与之前相同,但您还会在最后看到“3”。