# `Localize.List`
[🔗](https://github.com/elixir-localize/localize/blob/v0.39.0/lib/localize/list.ex#L1)

Formats lists into locale-aware strings using CLDR list
formatting patterns.

For example, a list of days like `["Monday", "Tuesday", "Wednesday"]`
can be formatted for a given locale:

    iex> Localize.List.to_string(["Monday", "Tuesday", "Wednesday"], locale: :en)
    {:ok, "Monday, Tuesday, and Wednesday"}

    iex> Localize.List.to_string(["Monday", "Tuesday", "Wednesday"], locale: :fr)
    {:ok, "Monday, Tuesday et Wednesday"}

## Element formatting

Each list element is formatted with `Localize.to_string/2`, which
dispatches via the `Localize.Chars` protocol. Strings pass through
unchanged. Numbers, dates, units, durations, currencies and any
other type with a `Localize.Chars` implementation are formatted
in a locale-aware way using the same locale (and any other
forwarded options) as the outer list call. Types with no
`Localize.Chars` implementation fall through to `Kernel.to_string/1`.

    iex> Localize.List.to_string([~D[2025-07-10], ~D[2025-08-15]], locale: :en)
    {:ok, "Jul 10, 2025 and Aug 15, 2025"}

    iex> Localize.List.to_string([1234, 5678], locale: :de)
    {:ok, "1.234 und 5.678"}

Options that are specific to list formatting (`:list_style`,
`:treat_middle_as_end`) are stripped before being passed to the
per-element formatters. Everything else (`:locale`, `:format`,
`:currency`, `:prefer`, etc.) is forwarded so that, for example,
a list of numbers can pick up a single `currency: :USD` option,
or a list of dates can pick up a single `format: :long` option:

    iex> Localize.List.to_string([1234.56, 5678.90], locale: :en, currency: :USD)
    {:ok, "$1,234.56 and $5,678.90"}

# `pattern_type`

```elixir
@type pattern_type() ::
  :or
  | :or_narrow
  | :or_short
  | :standard
  | :standard_narrow
  | :standard_short
  | :unit
  | :unit_narrow
  | :unit_short
```

# `intersperse`

```elixir
@spec intersperse([term()], Keyword.t()) :: {:ok, [term()]} | {:error, Exception.t()}
```

Intersperses list elements with locale-appropriate separators.

This function returns a list with separator strings inserted
between elements, which is useful for building safe HTML or
other non-string output.

### Arguments

* `list` is a list of terms.

* `options` is a keyword list of options. Same options as
  `to_string/2`.

### Returns

* `{:ok, interspersed_list}` on success.

* `{:error, exception}` if the locale or format is invalid.

### Examples

    iex> Localize.List.intersperse(["a", "b", "c"], locale: :en)
    {:ok, ["a", ", ", "b", ", and ", "c"]}

    iex> Localize.List.intersperse(["a", "b", "c"], locale: :en, list_style: :unit_narrow)
    {:ok, ["a", " ", "b", " ", "c"]}

    iex> Localize.List.intersperse(["a"], locale: :en)
    {:ok, ["a"]}

    iex> Localize.List.intersperse([1, 2], locale: :en)
    {:ok, [1, " and ", 2]}

# `intersperse!`

```elixir
@spec intersperse!([term()], Keyword.t()) :: [term()]
```

Same as `intersperse/2` but raises on error.

### Arguments

* `list` is a list of terms.

* `options` is a keyword list of options.

### Returns

* An interspersed list.

### Examples

    iex> Localize.List.intersperse!(["a", "b", "c"], locale: :en)
    ["a", ", ", "b", ", and ", "c"]

# `known_list_styles`

```elixir
@spec known_list_styles() :: [
  :or
  | :or_narrow
  | :or_short
  | :standard
  | :standard_narrow
  | :standard_short
  | :unit
  | :unit_narrow
  | :unit_short,
  ...
]
```

Returns the list of known list style names.

### Returns

* A list of atoms representing the known list style names.

### Examples

    iex> Localize.List.known_list_styles()
    [:or, :or_narrow, :or_short, :standard, :standard_narrow, :standard_short, :unit, :unit_narrow, :unit_short]

# `list_patterns_for`

```elixir
@spec list_patterns_for(atom() | String.t()) :: {:ok, map()} | {:error, Exception.t()}
```

Returns the list patterns for a locale.

### Arguments

* `locale` is a locale identifier.

### Returns

* `{:ok, patterns_map}` where each value is a
  `t:Localize.List.Pattern.t/0`.

* `{:error, exception}` if the locale is invalid.

### Examples

    iex> {:ok, patterns} = Localize.List.list_patterns_for(:en)
    iex> Map.keys(patterns) |> Enum.sort()
    [:or, :or_narrow, :or_short, :standard, :standard_narrow, :standard_short, :unit, :unit_narrow, :unit_short]

# `list_styles_for`

```elixir
@spec list_styles_for(atom() | String.t()) ::
  {:ok, [atom()]} | {:error, Exception.t()}
```

Returns the list style names available for a locale.

### Arguments

* `locale` is a locale identifier.

### Returns

* `{:ok, list_styles}` where `list_styles` is a sorted
  list of atoms.

* `{:error, exception}` if the locale is invalid.

### Examples

    iex> Localize.List.list_styles_for(:en)
    {:ok, [:or, :or_narrow, :or_short, :standard, :standard_narrow, :standard_short, :unit, :unit_narrow, :unit_short]}

# `to_string`

```elixir
@spec to_string([term()], Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
```

Formats a list into a string according to the list pattern
rules for a locale.

### Arguments

* `list` is a list of terms that can be passed through
  `Kernel.to_string/1`.

* `options` is a keyword list of options.

### Options

* `:locale` is a locale identifier. The default is `:en`.

* `:list_style` is an atom from `known_list_styles/0` or a
  `t:Localize.List.Pattern.t/0`. Selects the CLDR list pattern
  used to join the elements (`:standard`, `:or`, `:unit_narrow`,
  etc.). The default is `:standard`.

* `:treat_middle_as_end` is a boolean. When `true`, the
  `:middle` pattern is used for the last element instead
  of the `:end` pattern. The default is `false`.

All other options (e.g. `:format`, `:currency`, `:prefer`) are
forwarded to the per-element formatters via `Localize.to_string/2`.

### Returns

* `{:ok, formatted_string}` on success.

* `{:error, exception}` if the locale or list style is invalid.

### Examples

    iex> Localize.List.to_string(["a", "b", "c"], locale: :en)
    {:ok, "a, b, and c"}

    iex> Localize.List.to_string(["a", "b", "c"], locale: :en, list_style: :unit_narrow)
    {:ok, "a b c"}

    iex> Localize.List.to_string(["a"], locale: :en)
    {:ok, "a"}

    iex> Localize.List.to_string([1, 2], locale: :en)
    {:ok, "1 and 2"}

    iex> Localize.List.to_string([1, 2, 3, 4, 5, 6], locale: :en)
    {:ok, "1, 2, 3, 4, 5, and 6"}

# `to_string!`

```elixir
@spec to_string!([term()], Keyword.t()) :: String.t()
```

Same as `to_string/2` but raises on error.

### Arguments

* `list` is a list of terms.

* `options` is a keyword list of options.

### Returns

* A formatted string.

### Examples

    iex> Localize.List.to_string!(["a", "b", "c"], locale: :en)
    "a, b, and c"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
