
Ich habe eine Liste von Zeichenfolgen (Befehlszeichenfolgen) in einem Array gespeichert und dabei die folgende Antwort gegeben:https://tex.stackexchange.com/a/215571/61517. Nun wollte ich zufällig darauf zugreifen und habe daher einen Zufallszähler (mithilfe von lcq
) hinzugefügt:
\storedata{general}{{a}{b}{c}}
\reinitrand[counter=GenCounter, last=3]
\getdata[\value{GenCounter}]{general}
Mein Problem ist nun: Ich möchte das Array erweitern, general
indem ich weitere Befehle hinzufüge, muss dann aber auch den last
Wert für die \reinitrand[]
Funktion ändern, um auf alle Elemente zugreifen zu können. Gibt es eine Möglichkeit, dem \storedata
Makro einen Zähler hinzuzufügen, um die aktuelle Länge des Arrays anzuzeigen und das Reinit-Makro entsprechend einzustellen?
Mein endgültiges Ziel ist es, zufällig auf alle Elemente im Array zuzugreifen, unabhängig von der Anzahl der Elemente im Array, ohne das mögliche Problem einer Out-of-Bounds-Exception zu haben, die zu nichts führt. Darüber hinaus möchte ich den last
Wert der zufälligen Initialisierung nicht jedes Mal ändern, wenn ich die Anzahl der Befehle im Array ändere, er sollte sich selbst aktualisieren.
Erweiterung 2: Mein Code sieht so aus (entnommen aus der oben angegebenen Antwort):
\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}
Wie erhalte ich die Länge von mydata
, also das Ergebnis von \printlength
?
Antwort1
Die Verwendung \seq_count:N
in einem Wrapper-Befehl liefert die Anzahl der Elemente in der Sequenz.
Hier \seq_count:c
muss die Variante verwendet werden, da der Sequenzname generiert wird und in einem \l_...seq
ähnlichen Befehlsnamen zuvor nicht bekannt war.
Wie man sieht, \printlength
ist das Makro erweiterbar.
\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}