Типы списков

Логика форматирования списков в CLDR

В интернационализации JavaScript списки представляют собой не просто соединение элементов через запятую или союз. В разных языках правила перечисления зависят от синтаксиса, пунктуации и семантики. Библиотека Globalize опирается на данные CLDR (Unicode Common Locale Data Repository), где для каждого языка определены правила построения списков с учётом локали.

Форматирование списка в Globalize выполняется через единый механизм, который учитывает:

  • тип списка (семантическую природу соединения элементов),
  • стиль отображения,
  • локаль пользователя.

Основные типы списков

Conjunction (соединительный список)

Соединительный тип используется для перечислений, где элементы объединяются логически как группа.

Примеры значений:

  • «и»
  • «, и»
  • «и также»

В английском:

  • “A, B, and C”

В русском:

  • “A, B и C”

Особенность заключается в том, что последний элемент может получать особую связку, отличную от остальных разделителей.

Пример использования в Globalize

Globalize.formatList(["яблоко", "груша", "слива"], {
  type: "conjunction"
});

Результат зависит от локали:

  • ru: «яблоко, груша и слива»
  • en: “apple, pear, and plum”

Disjunction (разделительный список)

Разделительный тип применяется, когда элементы являются альтернативами.

Примеры значений:

  • «или»
  • «либо»
  • «или/или»

В английском:

  • “A, B, or C”

В русском:

  • “A, B или C”

Семантика здесь критична: элементы не объединяются, а рассматриваются как взаимоисключающие варианты.

Пример использования

Globalize.formatList(["HTML", "CSS", "JavaScript"], {
  type: "disjunction"
});

Результат:

  • ru: «HTML, CSS или JavaScript»
  • en: “HTML, CSS, or JavaScript”

Unit (список единиц)

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

Примеры:

  • «5 м, 10 см»
  • «2 часа 30 минут»
  • «3 кг и 200 г»

Особенность unit-списков заключается в том, что они часто подчиняются более строгим правилам форматирования, чем обычные перечисления. В некоторых локалях может отсутствовать союз перед последним элементом или использоваться более компактная форма.

Пример использования

Globalize.formatList(["2 часа", "30 минут"], {
  type: "unit"
});

Результат:

  • ru: «2 часа 30 минут»
  • en: “2 hours, 30 minutes”

Структура стилей списков

Помимо семантического типа, списки поддерживают стили представления.

Long (полный стиль)

Используется в стандартных текстах, документации и интерфейсах.

Примеры:

  • “A, B и C”
  • “A, B, and C”

Данный стиль обеспечивает максимальную читаемость.


Short (сокращённый стиль)

Применяется в ограниченном пространстве интерфейса.

Примеры:

  • “A, B & C”
  • “A, B, C”

В некоторых локалях стиль может совпадать с long при отсутствии специфических сокращений.


Narrow (сжатый стиль)

Используется в крайне ограниченных пространствах, например в мобильных интерфейсах или таблицах.

Примеры:

  • “A B C”
  • “A, B, C” без союзов

В ряде локалей может полностью исключать связующие элементы.


Поведение в зависимости от локали

CLDR определяет правила для каждой локали отдельно, включая:

  • порядок соединений,
  • наличие оксфордской запятой,
  • выбор союза перед последним элементом,
  • использование пробелов и знаков препинания.

Пример различий

Globalize.formatList(["red", "green", "blue"], {
  type: "conjunction"
});

Результаты:

  • en: “red, green, and blue”
  • en-GB: “red, green and blue”
  • ru: “red, green и blue”

Оксфордская запятая

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

Пример:

  • “A, B, and C” (с запятой)
  • “A, B and C” (без запятой)

Globalize не принимает решение самостоятельно — поведение определяется данными CLDR.


Пустые и единичные списки

Один элемент

При одном элементе форматирование списка фактически не применяется:

Globalize.formatList(["A"], { type: "conjunction" });

Результат:

  • “A”

Два элемента

Для двух элементов часто используется упрощённая форма без промежуточного разделителя:

  • ru: “A и B”
  • en: “A and B”

Пустой список

Пустые массивы обычно возвращают пустую строку или результат, зависящий от реализации:

Globalize.formatList([], { type: "conjunction" });

Результат:

  • “”

Комбинации типов и стилей

Тип и стиль могут комбинироваться, создавая множество вариантов форматирования.

Globalize.formatList(["A", "B", "C"], {
  type: "conjunction",
  style: "short"
});

Возможные эффекты:

  • сокращённые союзы,
  • минимизация знаков препинания,
  • адаптация под интерфейс.

Вложенные списки

При вложенных структурах применяется последовательное форматирование:

[
  ["A1", "A2"],
  ["B1", "B2"]
]

Сначала форматируется внутренний список, затем внешний:

  • “A1, A2 и B1, B2”

Такие случаи требуют осторожности, поскольку семантика может теряться при избыточной вложенности.


Локализация и зависимости от данных CLDR

Работа типов списков полностью зависит от наличия корректных CLDR-данных:

  • patterns для conjunction,
  • patterns для disjunction,
  • patterns для unit,
  • правила пунктуации.

Отсутствие данных приводит к fallback-логике, которая может быть упрощённой и не учитывать особенности языка.


Особенности интеграции в интерфейсные системы

При использовании списков в интерфейсах часто учитываются дополнительные ограничения:

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

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


Производительность форматирования списков

Форматирование списков в Globalize связано с:

  • загрузкой CLDR-данных,
  • кэшированием локалей,
  • повторным использованием formatter-объектов.

Оптимизация достигается через:

  • переиспользование Globalize instance,
  • минимизацию переключений локали,
  • предварительную инициализацию нужных CLDR пакетов.