
Armazenei uma lista de strings (strings de comando) em um array seguindo a resposta aqui:https://tex.stackexchange.com/a/215571/61517. Agora eu queria acessá-los aleatoriamente e, portanto, adicionei um contador aleatório (usando lcq
) a ele:
\storedata{general}{{a}{b}{c}}
\reinitrand[counter=GenCounter, last=3]
\getdata[\value{GenCounter}]{general}
Meu problema agora é: quero expandir o general
-array adicionando mais comandos a ele, mas também preciso modificar o last
-value da \reinitrand[]
-function para acessar todos os elementos. Existe a possibilidade de adicionar um contador ao \storedata
-macro para ver o comprimento atual da matriz e definir o reinit-macro de acordo?
Meu objetivo final é acessar todos os elementos do array aleatoriamente, independentemente do número de elementos do array, sem ter o possível problema de uma exceção fora dos limites resultando em nada. Além disso, não quero alterar o last
valor da inicialização aleatória toda vez que alterar a quantidade de comandos no array, ele deve se atualizar.
Extensão 2: Meu código se parece com (retirado da resposta mencionada acima):
\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}
Como obtenho o comprimento de mydata
, ou seja, o resultado de \printlength
?
Responder1
Usar \seq_count:N
um comando wrapper fornecerá o número de elementos na sequência.
Aqui a variante \seq_count:c
deve ser usada, pois o nome da sequência é gerado e não é conhecido antes em um \l_...seq
nome de comando semelhante.
Como pode ser visto, a \printlength
macro é expansível.
\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}