# How to know the number of elements in a clist in LaTeX3?

I could not find in the LaTeX3 documentation any function to count the number of elements in a clist. So I coded my own, but it is likely to be very suboptimal.

Is there any better alternative?

To be precise, \clist_count:NN stores in its first argument (of type int) the length of its second argument (a clist)

\cs_new:Nn \clist_count:NN
{
\int_set:Nn \l_tmpa_int {0}
\clist_set_eq:NN \l_tmpa_clist #2
\bool_until_do:nn
{
\clist_if_empty_p:N \l_tmpa_clist
}{
\clist_pop:NN \l_tmpa_clist \l_tmpa_tl
\int_add:Nn \l_tmpa_int {1}
}
\int_set_eq:NN #1 \l_tmpa_int
}


I am also interested in a function that would pick the n-th element of a clist.

## 1 Answer

EDIT (by Bruno): the correct function to use now is \clist_count:N, which essentially derives from Will's implementation below. There is also \clist_count:n which expects an explicit comma separated list as its argument rather than a list stored inside a variable. Both functions expand to an explicit integer.

Here's a solution that should be quite a bit faster (although I haven't tested it):

\cs_new:Npn \clist_length:N #1 {
\int_eval:n {
0 \clist_map_function:NN #1 \tl_elt_count_aux:n
}
}


Here, \clist_length:N expands to the length of the comma-list; it's expandable, so you can use it inside \int_set:Nn if you like.

And here's a solution for expandably extracting the n-th item of a comma list:

\cs_new:Nn \clist_nth:Nn {
\int_compare:nTF { \clist_length:N #1 < #2 }
{ \ERROR }
{
\exp_after:wN \clist_nth_aux:nn \exp_after:wN {#1} #2
}
}
\cs_new:Nn \clist_nth_aux:nn {
\clist_nth_aux_i:nnnw {1}{#2} #1 , \q_recursion_tail \q_recursion_stop
}
\cs_new:Npn \clist_nth_aux_i:nnnw #1#2#3, {
\quark_if_recursion_tail_stop:n {#3}
\int_compare:nTF {#1==#2}
{
\use_i_delimit_by_q_recursion_stop:nw {#3}
}
{
\clist_nth_aux_i:fnnw { \int_eval:n {#1+1} } {#2}
}
}
\cs_generate_variant:Nn \clist_nth_aux_i:nnnw {f}


Thanks for these questions; I've been meaning to add them to l3clist for a little while. P.S. Sorry for the slow reply!

• Thank you, that should reduce the size of my randomwalk package a bit: I'm new to writing packages, and to LaTeX3, so your answer is very useful. Since users don't always have the latest version of expl3, does it make sense to provide definitions of these most recent macros inside my package? – Bruno Le Floch Jan 23 '11 at 10:02
• @Bruno — Yes, for the time being; just check for their existence before overwriting them (\cs_if_free:NT). I would be very interested in hearing your thoughts on using expl3 as a relatively new package author; please don't hesitate to write any comments to me directly. – Will Robertson Jan 23 '11 at 11:09
• — I sent an email to the address you use for LaTeX-L. – Bruno Le Floch Jan 25 '11 at 17:32