Категории CLDR: zero, one, two, few, many, other

Система множественных форм в Unicode CLDR (Common Locale Data Repository) является основой для интернационализации числовых выражений в современных JavaScript-библиотеках, включая FormatJS. Она определяет набор категорий, которые используются для выбора правильной формы слова в зависимости от числа.

В FormatJS и API Intl.PluralRules эти категории применяются для построения локализованных сообщений, где грамматическая форма зависит от числового значения.


Назначение категорий множественного числа

Разные языки по-разному обрабатывают числа. В английском языке достаточно двух форм:

  • one (1 item)
  • other (2, 3, 4, 0 items)

В то время как в других языках система значительно сложнее. CLDR вводит унифицированный набор категорий:

  • zero
  • one
  • two
  • few
  • many
  • other

Каждая локаль использует подмножество этих категорий.


Категория zero

Категория zero используется в языках, где ноль имеет отдельную грамматическую форму.

Примеры поведения:

  • В некоторых языках ноль трактуется как особая форма
  • В других языках ноль входит в категорию other

Пример использования через Intl.PluralRules:

const pr = new Intl.PluralRules('ar');
pr.select(0); // "zero"

Категория one

Категория one соответствует форме единственного числа.

Она присутствует в большинстве языков, но её математическое определение зависит от локали.

Примеры:

  • английский: 1 → one
  • русский: 1 → one (но с дополнительными категориями для других чисел)
  • французский: 0 и 1 часто относятся к one или other в зависимости от правил
const pr = new Intl.PluralRules('en');
pr.select(1); // "one"

Категория two

Категория two встречается в ограниченном числе языков и используется для обозначения пары или двойственного числа.

Характерные особенности:

  • используется в арабском (частично)
  • присутствует в словенском и некоторых семитских языках
const pr = new Intl.PluralRules('ar');
pr.select(2); // "two"

Категория few

Категория few используется для небольших чисел, которые не равны 1 или 2, но попадают в специальный грамматический диапазон.

Особенности:

  • широко используется в славянских языках
  • охватывает диапазоны вроде 3–4 в русском языке

Пример для русского языка:

const pr = new Intl.PluralRules('ru');
pr.select(3); // "few"
pr.select(4); // "few"

Категория many

Категория many применяется для больших чисел или специфических диапазонов, которые не подпадают под one, few или other.

Особенности:

  • присутствует в арабской локали
  • может охватывать десятки и сотни в зависимости от языка
const pr = new Intl.PluralRules('ar');
pr.select(11); // "many"
pr.select(100); // "many"

Категория other

Категория other является универсальной и используется как fallback.

Она применяется:

  • если число не соответствует другим категориям
  • в языках с простой системой множественного числа (например, английский)

Пример:

const pr = new Intl.PluralRules('en');
pr.select(5); // "other"
pr.select(0); // "other"

Взаимосвязь с FormatJS

FormatJS использует CLDR через Intl.PluralRules и ICU Message Syntax.

Пример сообщения:

import { defineMessages, useIntl } from 'react-intl';

const messages = defineMessages({
  items: {
    id: 'cart.items',
    defaultMessage: `
      {count, plural,
        one {# товар}
        few {# товара}
        many {# товаров}
        other {# товара}
      }
    `
  }
});

В этом примере движок выбирает форму в зависимости от категории, возвращаемой CLDR.


Поведение в разных языках

Английский (en)

Используются только:

  • one
  • other
1 → one
2, 3, 10 → other

Русский (ru)

Используются:

  • one
  • few
  • many
  • other (редко)
1 → one
2–4 → few
5–20 → many

Арабский (ar)

Используются все категории:

  • zero
  • one
  • two
  • few
  • many
  • other
0 → zero
1 → one
2 → two
3–10 → few
11–99 → many
100+ → other

Логика выбора категории

Определение категории происходит через алгоритмы CLDR, основанные на:

  • целой части числа
  • остатке от деления
  • десятичной части
  • локальных грамматических правилах языка

JavaScript API инкапсулирует эти правила:

const pr = new Intl.PluralRules('ru');

pr.select(21); // "one"
pr.select(22); // "few"
pr.select(25); // "many"

Использование в ICU-синтаксисе

FormatJS применяет ICU MessageFormat, где категории напрямую связаны с ключами:

{value, plural,
  zero {нет элементов}
  one {# элемент}
  few {# элемента}
  many {# элементов}
  other {# элемента}
}

Каждая ветка соответствует конкретной категории CLDR.


Типичные ошибки при работе с категориями

Частые проблемы при реализации:

  • отсутствие поддержки всех категорий локали
  • использование только one/other для языков со сложной морфологией
  • неверное предположение, что категории универсальны для всех языков
  • игнорирование zero, что приводит к некорректным формулировкам

Связь с Intl.PluralRules

Нативный API JavaScript полностью основан на CLDR:

new Intl.PluralRules('ru').resolvedOptions();

Результат включает информацию о локали и типе правил, но не раскрывает внутренние диапазоны — они определяются CLDR.


Роль CLDR в интернационализации

CLDR выполняет функцию стандарта, обеспечивающего:

  • унификацию правил множественных форм
  • согласованность между платформами
  • предсказуемость поведения FormatJS и Intl API
  • поддержку сотен языков без ручного описания правил

Система категорий позволяет отделить логику языка от кода приложения, делая форматирование чисел декларативным.