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
    \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.


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? 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. Jan 23 '11 at 11:09
  • — I sent an email to the address you use for LaTeX-L. Jan 25 '11 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.