
Guardé una lista de cadenas (cadenas de comando) en una matriz siguiendo la respuesta aquí:https://tex.stackexchange.com/a/215571/61517. Ahora quería acceder a ellos aleatoriamente y, por lo tanto, lcq
le agregué un contador aleatorio (usando):
\storedata{general}{{a}{b}{c}}
\reinitrand[counter=GenCounter, last=3]
\getdata[\value{GenCounter}]{general}
Mi problema ahora es: quiero expandir la general
matriz agregándole más comandos, pero luego también tengo que modificar el last
valor de la \reinitrand[]
función para poder acceder a todos los elementos. ¿Existe la posibilidad de agregar un contador a la \storedata
macro para ver la longitud actual de la matriz y configurar la macro de reinicio en consecuencia?
Mi objetivo final es acceder a todos los elementos de la matriz de forma aleatoria, independientemente del número de elementos de la matriz, sin tener el posible problema de una excepción fuera de límites que no resulte en nada. Además, no quiero cambiar el last
valor de la inicialización aleatoria cada vez que cambio la cantidad de comandos en la matriz, debería actualizarse solo.
Extensión 2: Mi código se ve así (tomado de la respuesta mencionada anteriormente):
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\storedata}{mm}
{
\bcp_store_data:nn { #1 } { #2 }
}
\NewDocumentCommand{\appenddata}{mm}
{
\bcp_append_data:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getdata}{O{1}m}
{
\bcp_get_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \bcp_store_data:nn #1 #2
{
% create the sequence if it doesn't exist or clear it if it exists
\seq_if_exist:cTF { l_bcp_data_#1_seq }
{ \seq_new:c { l_bcp_data_#1_seq } }
{ \seq_clear:c { l_bcp_data_#1_seq } }
% append the items
\__bcp_append_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \bcp_append_data:nn #1 #2
{
% create the sequence if it doesn't exist, do nothing if it exists
\seq_if_exist:cF { l_bcp_data_#1_seq }
{ \seq_new:c { l_bcp_data_#1_seq } }
% append the items
\__bcp_append_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \__bcp_append_data:nn #1 #2
{
% append items one at a time
\tl_map_inline:nn { #2 }
{
\seq_put_right:cn { l_bcp_data_#1_seq } { ##1 }
}
}
\cs_new:Npn \bcp_get_data:nn #1 #2
{
% retrieve the requested item
\seq_item:cn { l_bcp_data_#2_seq } { #1 }
}
\ExplSyntaxOff
\begin{document}
\storedata{mydata}{{one}{two}}
\appenddata{mydata}{{three}{four}}
\getdata[1]{mydata}
\getdata[2]{mydata}
\getdata[3]{mydata}
\getdata[4]{mydata}
\printlength{mydata}% How can I define this function?
\end{document}
¿Cómo obtengo la longitud de mydata
, es decir, el resultado de \printlength
?
Respuesta1
El uso \seq_count:N
de un comando contenedor proporcionará la cantidad de elementos en la secuencia.
\seq_count:c
Aquí se debe utilizar la variante ya que el nombre de la secuencia se genera y no se conocía antes en un \l_...seq
nombre de comando similar.
Como puede verse, la \printlength
macro es ampliable.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\storedata}{mm}
{
\bcp_store_data:nn { #1 } { #2 }
}
\NewDocumentCommand{\appenddata}{mm}
{
\bcp_append_data:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getdata}{O{1}m}
{
\bcp_get_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \bcp_store_data:nn #1 #2
{
% create the sequence if it doesn't exist or clear it if it exists
\seq_if_exist:cTF { l_bcp_data_#1_seq }
{ \seq_new:c { l_bcp_data_#1_seq } }
{ \seq_clear:c { l_bcp_data_#1_seq } }
% append the items
\__bcp_append_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \bcp_append_data:nn #1 #2
{
% create the sequence if it doesn't exist, do nothing if it exists
\seq_if_exist:cF { l_bcp_data_#1_seq }
{ \seq_new:c { l_bcp_data_#1_seq } }
% append the items
\__bcp_append_data:nn { #1 } { #2 }
}
\cs_new_protected:Npn \__bcp_append_data:nn #1 #2
{
% append items one at a time
\tl_map_inline:nn { #2 }
{
\seq_put_right:cn { l_bcp_data_#1_seq } { ##1 }
}
}
\cs_new:Npn \bcp_get_data:nn #1 #2
{
% retrieve the requested item
\seq_item:cn { l_bcp_data_#2_seq } { #1 }
}
\newcommand{\printlength}[1]{%
\seq_count:c { l_bcp_data_#1_seq }
}
\ExplSyntaxOff
\begin{document}
\storedata{mydata}{{one}{two}}
\appenddata{mydata}{{three}{four}}
\getdata[1]{mydata}
\getdata[2]{mydata}
\getdata[3]{mydata}
\getdata[4]{mydata}
\ifnum\printlength{mydata} > 1\relax
Hooray% How can I define this function?
\else
Nope!
\fi
\end{document}