TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
up vote 10 down vote accepted

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!

share|improve this answer
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

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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