joinDisplayList method

  1. @useResult
String? joinDisplayList({
  1. String joiner = ', ',
  2. String doubleJoiner = ' and ',
  3. String lastJoiner = ', and ',
  4. bool isUnique = true,
})

Joins these strings into a natural-language list with an Oxford comma: one item is itself, two become 'a and b', three or more become 'a, b, and c'.

Each entry is trimmed and blank/whitespace-only entries are dropped before counting, so [' ', 'a', ''] collapses to a single item rather than emitting stray separators. When isUnique is true (default) duplicates are removed via toUnique (first-seen order preserved). Returns null — not '' — when nothing remains after trimming, so a caller can tell "no items" apart from a real joined string.

The joiners are caller-controlled for locale/style:

  • joiner separates the leading items in the 3+ case (default ', ').
  • doubleJoiner joins exactly two items (default ' and ').
  • lastJoiner precedes the final item in the 3+ case (default ', and ', the Oxford comma).

Example:

['Alice', 'Bob', 'Carol'].joinDisplayList(); // 'Alice, Bob, and Carol'
['Alice', 'Bob'].joinDisplayList();          // 'Alice and Bob'
['Alice'].joinDisplayList();                 // 'Alice'
<String>[].joinDisplayList();                // null

Audited: 2026-06-12 11:26 EDT

Implementation

@useResult
String? joinDisplayList({
  String joiner = ', ',
  String doubleJoiner = ' and ',
  String lastJoiner = ', and ',
  bool isUnique = true,
}) {
  // Trim and drop blanks before counting so the length-based branching below
  // sees the real item count, not entries that would render as empty.
  final List<String> trimmed = <String>[
    for (final String s in this)
      if (s.trim().isNotEmpty) s.trim(),
  ];

  final List<String> list = isUnique ? trimmed.toUnique() : trimmed;
  if (list.isEmpty) {
    return null;
  }

  // first/last are safe here: each branch runs only after its length is
  // proven, so the list is never empty at the access site.
  if (list.length == 1) {
    return list.first;
  }

  if (list.length == 2) {
    return '${list.first}$doubleJoiner${list.last}';
  }

  // 3+ items: lead items joined by [joiner], then the Oxford [lastJoiner].
  return list.takeSafe(list.length - 1).join(joiner) + lastJoiner + list.last;
}