Formatting Language-Sensitive Lists in JavaScript with ListFormat
Tags: webdev, programming, javascript, beginners
Published: 2021-01-30 21:31:42

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

With the `Intl.ListFormat` constructor, we can format language-sensitive lists with ease. It lets us set the locale in which to format a list. Also, it lets us set options for formatting lists such as the type of list or style of the list. To use it, we can create a new `ListFormat` object with the `Intl.ListFormat` constructor.

The constructor takes up to two arguments. The first argument is a string of the locale that you want to format the list for. The second argument takes an object with the options for formatting and styling the list. An example use of the `Intl.ListFormat` constructor is:

```
const arr = ['bus', 'car', 'train'];
const formatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

If we run the code above, we will see _bus_, _car_, _and_ _train_ logged from the `console.log` statement. The `Intl.ListFormat` constructor creates a formatter object that has the `format` method to convert an array into a list according to the locale and formatting options that we set.

In the example above, we set the locale to `en` for English, we set the `style` property to `long`, which formats an array of strings into something like _A_, _B_, _and C_ or _A, B, or C_. The `type` property specifies the kind of list we want to format the list into. Conjunction means that we format a list into _A, B, and C_.

The arguments of the constructor are the locales that you want to format the list into. It can be a string or an array of strings containing the locale of the list you want to format it into. The locale string or strings should be a BCP 47 language tag. The `locales` argument is optional. An abridged list of BCP-47 language tags includes:

```
ar — Arabic

bg — Bulgarian

ca — Catalan

zh-Hans — Chinese, Han (Simplified variant)

cs — Czech

da — Danish

de — German

el — Modern Greek (1453 and later)

en — English

es — Spanish

fi — Finnish

fr — French

he — Hebrew

hu — Hungarian

is — Icelandic

it — Italian

ja — Japanese

ko — Korean

nl — Dutch

no — Norwegian

pl — Polish

pt — Portuguese

rm — Romansh

ro — Romanian

ru — Russian

hr — Croatian

sk — Slovak

sq — Albanian

sv — Swedish

th — Thai

tr — Turkish

ur — Urdu

id — Indonesian
```

The second argument for the constructor is an object that lets us set the options for how to format the list’s string. There are three properties for this object: `localeMatcher`, `type`, and `style`. The `localeMatcher` option specifies the locale-matching algorithm to use. The possible values are `lookup` and `best fit`.

The `lookup` algorithm searches for the locale until it finds the one that fits the character set of the strings that are being compared.

`best fit` finds the locale that is at least as, but possibly more, suitable than the `lookup` algorithm.

The `type` property can take on two possible values: `conjunction`, `disjunction`, or `unit`. `conjunction` means that the list is joined with an _and_, as in _A, B, and C_. This is the default option. `disnjunction` means the list is joined with an _or_, as in _A, B, or C_.

`unit` stands for a list of values with units.

The `style` property specifies the length of the formatted message. There are two possible values for this property. It can either be `long` (e.g., _A, B, and C_), `short` (e.g., _A, B, C_), or `narrow` (e.g., _A B C_). When `style` is `short` or `narrow`, `unit` is the only allowed value for this option.

For example, we can use it to format a list into a string that is joined with an _and_ at the end. We can write the following to do so:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

If we log the `formattedList` constant like we did above, we get _bus, car, and bicycle_. We set the `en` locale to format the string for the English locale, with style `long` and as a conjunction, which means the list will be joined with an _and_ at the end. If we want to get an _or_-based list, we can change the `type` property to a `disjunction`, as in the following code:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'disjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

If we run the code above, then we get _bus, car, or bicycle_ logged in the `console.log` statement above.

We can convert it to a shorter list by using the `short` or `narrow` option for the `style` property. For example, we can write:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'short',
  type: 'conjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

Then we get _bus, car, & bicycle_ in the `console.log` output when we run the code above. The `short` and `disjunction` combination is the same as the `long` and `disjunction` combination. If we write:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'short',
  type: 'disjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

Then we get _bus, car, or bicycle_. The `narrow` option would make it even shorter. For example, if we put:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'narrow',
  type: 'conjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

Then we get _bus, car, bicycle_ logged in the `console.log` when we run the code above.

This also works for non-English locales. For example, if we want to format a list of Chinese strings into a list, we can write the following code:

```
const arr = ['日', '月', '星'];
const formatter = new Intl.ListFormat('zh-hant', {
  style: 'narrow',
  type: 'conjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

Then we get ‘日、月和星’, which means _sun, moon, and stars_. If we switch the `style` option to `long` or `short`, we would get the same thing because in Chinese there’s only one way to write a conjunction, unlike in English. `disjunction` also works with Chinese. For instance, if we have:

```
const arr = ['日', '月', '星'];
const formatter = new Intl.ListFormat('zh-hant', {
  style: 'long',
  type: 'disjunction'
});
const formattedList = formatter.format(arr);
console.log(formattedList);
```

Then we get ‘日、月或星’ which means _sun, moon, or stars_. If we switch the `style` option to `long` or `short`, as with Chinese conjunctions, we would get the same thing because in Chinese there’s only one way to write a disjunction, unlike in English.

### formatToParts() Method

In addition to the `format` method, the `Intl.ListFormat` instance also has the `formatToParts` method, which formats an array into a conjunction or disjunction string and then returns it as an array of the parts of the formatted string.

For example, if we want to return an array of the parts of the formatted English string for a list, then we can write the following code:

```
const arr = ['bus', 'car', 'bicycle'];
const formatter = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});
const formattedList = formatter.formatToParts(arr);
console.log(formattedList);
```

Then we get:

```
[
  {
    "type": "element",
    "value": "bus"
  },
  {
    "type": "literal",
    "value": ", "
  },
  {
    "type": "element",
    "value": "car"
  },
  {
    "type": "literal",
    "value": ", and "
  },
  {
    "type": "element",
    "value": "bicycle"
  }
]
```

from the `console.log` statement. These are the parts of the formatted string that we get with the `format` method, but broken apart into individual entries. This method is handy if we only want some parts of the formatted string.

With the `Intl.ListFormat` constructor, formatting language-sensitive lists is easy. The constructor takes a locale string or an array of locale strings as the first argument and an object with some options for the second argument. We can convert an array into a string that has the list formatted into conjunction or disjunction with the `Intl.ListFormat` instance’s `format` method, which takes a locale string and options for the length style of the formatted string and whether it’s a conjunction, disjunction, or unit string. It also has a `formatToParts` method to convert it to a formatted list and then break up the parts into an array.