5

What is the best way to write a sequence of comma-separated values in math mode? Currently, I'm using

$ s_1 $, $s_2$, $s_3$, $s_4$, $\dots $

But that is really tedious. Is there a more elegant way?

4
  • 1
    The answer depends on what s_1, s_2, etc denote: Are they a part of a sequence or another, at least somewhat ordered collection of "things" (numbers, right?), or are they just a bunch of unrelated variables/numbers? Please clarify.
    – Mico
    Mar 3, 2018 at 6:15
  • I think that the word "List" have to removed from the title because it is misleading... [LaTeX is still a programming language and a list (even more a comma separated list) makes people to think of data type or at list of some (tikz) loop than what you really mean]
    – koleygr
    Mar 3, 2018 at 6:53
  • 1
    @koleygr first thought shouldn't be TikZ but \@for-loop :)
    – Skillmon
    Mar 3, 2018 at 11:12
  • @Skillmon my first use of loop in latex was in tikz... Then show some more things... Anyway tikz is in parenthesis and the explanation is this comment...:P.
    – koleygr
    Mar 3, 2018 at 11:34

2 Answers 2

7

As was noted, because of fonts, it is best not to set the text list fully in math mode. Here is a quick macro to do it for you, with text mode commas.

An optional argument has been added, to determine how the list ends. The default is to end the list with , \ldots. If an optional argument is provided, the list is finite:

  1. If the optional argument is blank, there is nothing added to the underlying list, but

  2. if the optional argument is something else, the list is extended via \ldots out to the index specified in the optional argument.

Here is the MWE.

\documentclass{article}
\usepackage{listofitems}
\newcommand\textlist[3][\cr]{%
  \readlist\indices{#3}%
  \foreachitem\x\in\indices{%
    \ifnum\xcnt=1\else, \fi$#2_{\x}$%
  }%
  \ifx\cr#1\relax, \ldots\else%
    \if\relax#1\relax\else, \ldots, $#2_{#1}$\fi%
  \fi%
}
\begin{document}
Infinite list: \textlist{s}{1,2,3,4}.

Finite list: \textlist[]{\alpha}{2,4,6}.

Extended finite list: \textlist[13]{a}{1,2,3}.

Ending on a separate index: \textlist[j]{a}{1,2,3}.
\end{document}

enter image description here


Per OP's request, here is the alternate version where no optional argument signifies a finite list (no \ldots) and a blank optional argument signifies an infinite list. The extended finite list remains unchanged in syntax:

\documentclass{article}
\usepackage{listofitems}
\newcommand\textlist[3][\cr]{%
  \readlist\indices{#3}%
  \foreachitem\x\in\indices{%
    \ifnum\xcnt=1\else, \fi$#2_{\x}$%
  }%
  \ifx\cr#1\relax\else%
    \if\relax#1\relax, \ldots\else, \ldots, $#2_{#1}$\fi%
  \fi%
}
\begin{document}
Infinite list: \textlist[]{s}{1,2,3,4}.

Finite list: \textlist{\alpha}{2,4,6}.

Extended finite list: \textlist[13]{a}{1,2,3}.

Ending on a separate index: \textlist[j]{a}{1,2,3}.
\end{document}
2
  • This is really slick. The only thing I would change is to make: Finite list: \textlist{\alpha}{2,4,6}. Infinite list: \textlist[]{s}{1,2,3,4}. The rationale behind this is that the number in the [] seems to signify the ending value, so if it is left off, then what you see is what you get, and if it is blank, then there is no ending value (i.e. infinity).
    – Paul Wintz
    Mar 3, 2018 at 22:22
  • 1
    @PaulrBear Thanks. The alternative version is now provided at the end of my answer to do as you ask. Mar 4, 2018 at 0:54
1

Here's a flexible syntax. The trailing dots are added if we call \makelist*.

The final \parbox shows what line breaks are possible. It's best to use \dotsc (dots with commas) instead of \dots or \ldots, to preserve “input independence”.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\makelist}{sm}
 {
  \paul_makelist:n { #2 }
  \IfBooleanT{ #1 } { ,\nobreakspace$\dotsc$ }
 }

\seq_new:N \l__paul_list_input_seq
\seq_new:N \l__paul_list_output_seq

\cs_new_protected:Nn \paul_makelist:n
 {
  % split the list at commas
  \seq_set_from_clist:Nn \l__paul_list_input_seq { #1 }
  % substitute each item with \__paul_list_addmath:n { <item> }
  \seq_set_map:NNn
   \l__paul_list_output_seq 
   \l__paul_list_input_seq 
   { \__paul_list_addmath:n { \exp_not:n { ##1 } } }
  % output the list with the stated separators
  \seq_use:Nnnn \l__paul_list_output_seq
   { ,\nobreakspace } % between two
   { ,~ } % between more than two
   { ,\nobreakspace } % between last two
 }
\cs_new_protected:Nn \__paul_list_addmath:n
 {
  % if the item is \dotsc, we want to have a non breaking space before it
  \str_if_eq:nnT { #1 } { \dotsc } { \unskip\nobreakspace }
  $#1$
 }
\ExplSyntaxOff

\begin{document}

A finite sequence \makelist{s_1,s_2,s_3}

Another finite sequence \makelist{s_1,s_2,\dots,s_n}

An infinite sequence \makelist*{s_1,s_2,s_3,s_4}

Another infinite sequence \makelist*{s_1,s_2,\dots,s_n}

\parbox[t]{0pt}{
\makelist{s_1,s_2,s_3}

\makelist{s_1,s_2,\dots,s_n}

\makelist*{s_1,s_2,s_3,s_4}

\makelist*{s_1,s_2,\dots,s_n}
}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .