Manejo de bucles en expl3

Manejo de bucles en expl3

Esperaba esto dentro \clist_map, pero no en este código. La pregunta "tonta", probablemente...

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\pairwise}{mmm}{
    \clist_set_eq:NN \l_tmpa_clist #1
    \clist_set_eq:NN \l_tmpb_clist #2
    \clist_clear:N #3
    \bool_until_do:nn {\clist_if_empty_p:N \l_tmpa_clist}{
        \clist_pop:NN \l_tmpa_clist \l_tmpa_tl
        \clist_pop:NN \l_tmpb_clist \l_tmpb_tl
        \clist_put_right:Nn #3 {\l_tmpa_tl / \l_tmpb_tl}
    }
}
\ExplSyntaxOff

\begin{document}

\def\this{1,2,3,4,5}
\def\that{a,b,c,d,e}

There is \{\this\} and \{\that\}.

\pairwise{\this}{\that}{\result}
\def\expected{1/a,2/b,3/c,4/d,5/e}

Why \{\result\} not equal \{\expected\}?

\end{document}

Respuesta1

El comando \clist_put_right:Nnlo dejará \l_tmpa_tlen el input, es decir en el momento de llamar \resultpara verificar la igualdad, \l_tmpa_tlcontiene 5y \l_tmpb_tlcontiene e.

Sin embargo, para obtener el contenido por pares X/Y, el valor actual de \l_tmpa_tly \l_tmpb_tldebe evaluarse (expandirse) y almacenarse en la \clistvariable, así que use el xtipo:

\clist_put_right:Nx #3 {\l_tmpa_tl/\l_tmpb_tl}

Lo más probable es que una \seqlista sea más rápida, pero esto depende del caso de uso.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\pairwise}{mmm}{
  \clist_set_eq:NN \l_tmpa_clist #1
  \clist_set_eq:NN \l_tmpb_clist #2
  \clist_clear:N #3
  \bool_until_do:nn {\clist_if_empty_p:N \l_tmpa_clist}{
    \clist_pop:NN \l_tmpa_clist \l_tmpa_tl
    \clist_pop:NN \l_tmpb_clist \l_tmpb_tl
    \clist_put_right:Nx #3 {\l_tmpa_tl / \l_tmpb_tl}
  }
}
\ExplSyntaxOff

\begin{document}

\def\this{1,2,3,4,5}
\def\that{a,b,c,d,e}

There is \{\this\} and \{\that\}.

\pairwise{\this}{\that}{\result}
\def\expected{1/a,2/b,3/c,4/d,5/e}

Now \{\result\} is equal to \{\expected\}?

\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

Tienes que usar elvalorde la variable de lista de tokens, no de la lista de tokens.

Aquí hay un enfoque diferente que utiliza secuencias y \seq_mapthread_function:NNN, que atraviesa dos secuencias y entrega los elementos a una función de dos argumentos.

Puede proporcionar un separador de salida diferente como argumento opcional para `\pairwise, así por ejemplo

\pairwise[|]{a,b}{1,2}{\result}

definiría \resulta a/1|b/2.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\pairwise}{O{,}mmm}
 {
  \seq_set_from_clist:No \l_komarov_first_seq { #2 }
  \seq_set_from_clist:No \l_komarov_second_seq { #3 }
  \seq_clear:N \l_komarov_output_seq
  \seq_mapthread_function:NNN
    \l_komarov_first_seq
    \l_komarov_second_seq
    \komarov_addentry:nn
  \tl_set:Nx #4 { \seq_use:Nn \l_komarov_output_seq { #1 } }
 }
\seq_new:N \l_komarov_first_seq
\seq_new:N \l_komarov_second_seq
\seq_new:N \l_komarov_output_seq
\cs_generate_variant:Nn \seq_set_from_clist:Nn { No }
\cs_new_protected:Nn \komarov_addentry:nn
 {
  \seq_put_right:Nn \l_komarov_output_seq { #1 / #2 }
 }
\ExplSyntaxOff

\begin{document}

\newcommand\this{1,2,3,4,5}
\newcommand\that{a,b,c,d,e}

There is \{\this\} and \{\that\}.

\pairwise{\this}{\that}{\result}
\newcommand\expected{1/a,2/b,3/c,4/d,5/e}

Now \{\result\} equals \{\expected\}

\pairwise{1,2,3,4,5}{a,b,c,d,e}{\newresult}

Also \{\newresult\} equals \{\expected\}

\end{document}

ingrese la descripción de la imagen aquí

información relacionada