Форматирование больших чисел в сокращённом виде — одна из наиболее востребованных задач локализации интерфейсов. В англоязычных приложениях часто используются записи вида:
1K25M7.3BВ русской локали аналогичная запись может выглядеть иначе:
1 тыс.25 млн7,3 млрдБиблиотека Globalize предоставляет встроенный механизм компактного форматирования чисел с учётом правил конкретной локали.
Компактная форма применяется в ситуациях, где пространство интерфейса ограничено:
Основная задача — уменьшить визуальный объём числа без потери смысла.
Для работы компактного форматирования необходимы данные CLDR.
const Globalize = require("globalize");
Globalize.load(
require("cldr-data/main/en/numbers.json"),
require("cldr-data/main/en/ca-gregorian.json"),
require("cldr-data/supplemental/likelySubtags.json"),
require("cldr-data/supplemental/numberingSystems.json"),
require("cldr-data/supplemental/plurals.json")
);
Globalize.locale("en");
Для русской локали:
Globalize.load(
require("cldr-data/main/ru/numbers.json")
);
Globalize.locale("ru");
numberFormatterКомпактное форматирование активируется через параметр
compact.
const formatter = Globalize.numberFormatter({
compact: "short"
});
Поддерживаются два режима:
| Режим | Описание |
|---|---|
short |
Короткая запись |
long |
Полная текстовая форма |
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(1200));
console.log(formatter(550000));
console.log(formatter(7200000));
Результат:
1.2K
550K
7.2M
const formatter = Globalize.numberFormatter({
compact: "long"
});
console.log(formatter(1200));
console.log(formatter(550000));
console.log(formatter(7200000));
Результат:
1.2 thousand
550 thousand
7.2 million
Globalize.locale("ru");
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(1200));
console.log(formatter(2500000));
console.log(formatter(7300000000));
Результат:
1,2 тыс.
2,5 млн
7,3 млрд
Globalize автоматически:
long для
русского языкаconst formatter = Globalize.numberFormatter({
compact: "long"
});
console.log(formatter(1200));
console.log(formatter(2500000));
Результат:
1,2 тысячи
2,5 миллиона
Globalize самостоятельно определяет, какое сокращение использовать.
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(999));
console.log(formatter(1000));
console.log(formatter(1500000));
console.log(formatter(9800000000));
Результат:
999
1K
1.5M
9.8B
Масштаб выбирается автоматически:
| Диапазон | Суффикс |
|---|---|
| Тысячи | K / тыс. |
| Миллионы | M / млн |
| Миллиарды | B / млрд |
| Триллионы | T / трлн |
maximumFractionDigitsconst formatter = Globalize.numberFormatter({
compact: "short",
maximumFractionDigits: 1
});
console.log(formatter(1250));
console.log(formatter(9876543));
Результат:
1.3K
9.9M
const formatter = Globalize.numberFormatter({
compact: "short",
maximumFractionDigits: 0
});
console.log(formatter(1250));
console.log(formatter(9876543));
Результат:
1K
10M
const formatter = Globalize.numberFormatter({
compact: "short",
minimumFractionDigits: 2
});
console.log(formatter(1200));
Результат:
1.20K
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(-1200));
console.log(formatter(-7800000));
Результат:
-1.2K
-7.8M
console.log(formatter(0));
Результат:
0
Компактная запись для нуля не применяется.
console.log(formatter(12));
console.log(formatter(999));
Результат:
12
999
Сокращение используется только начиная с определённых порогов.
const formatter = Globalize.numberFormatter({
style: "percent",
compact: "short"
});
console.log(formatter(1200));
Подобные комбинации обычно не используются на практике. Некоторые локали могут поддерживать их некорректно.
const formatter = Globalize.numberFormatter({
style: "currency",
currency: "USD",
compact: "short"
});
console.log(formatter(1250000));
Возможный результат:
$1.3M
Для русской локали:
Globalize.locale("ru");
const formatter = Globalize.numberFormatter({
style: "currency",
currency: "RUB",
compact: "short"
});
console.log(formatter(1500000));
Результат:
1,5 млн ₽
const formatter = Globalize.numberFormatter({
compact: "short",
maximumFractionDigits: 1
});
const revenue = 25400000;
console.log(formatter(revenue));
Результат:
25.4M
console.log(formatter(1200));
console.log(formatter(58200));
console.log(formatter(990000));
Результат:
1.2K
58.2K
990K
console.log(formatter(150000000));
Результат:
150M
formatMessageКомпактные числа могут вставляться в локализованные сообщения.
const numberFormatter = Globalize.numberFormatter({
compact: "short"
});
const users = numberFormatter(2500000);
console.log(`Users online: ${users}`);
Результат:
Users online: 2.5M
Создание форматтера — относительно затратная операция.
Неправильно:
function format(value) {
return Globalize.numberFormatter({
compact: "short"
})(value);
}
Правильно:
const formatter = Globalize.numberFormatter({
compact: "short"
});
function format(value) {
return formatter(value);
}
В production-среде рекомендуется использовать предварительную компиляцию через:
globalize-compilerglobalize-webpack-pluginЭто позволяет:
Компактные обозначения отличаются в разных языках.
1.2K
5M
7B
1,2 тыс.
5 млн
7 млрд
120万
Некоторые языки используют совершенно другие единицы измерения больших чисел.
1254300
После форматирования:
1.3M
Точное значение теряется.
Компактная форма плохо подходит для:
Globalize использует данные CLDR и обеспечивает более предсказуемое
поведение, чем нативный Intl в старых окружениях, однако
итоговое отображение всё равно зависит от версии данных локализации.
Intl.NumberFormatconst formatter = new Intl.NumberFormat("en", {
notation: "compact",
compactDisplay: "short"
});
console.log(formatter.format(1200000));
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(1200000));
Globalize.locale("ru");
const compact = Globalize.numberFormatter({
compact: "short",
maximumFractionDigits: 1
});
const stats = {
users: 12500,
downloads: 728000,
revenue: 15400000
};
console.log({
users: compact(stats.users),
downloads: compact(stats.downloads),
revenue: compact(stats.revenue)
});
Результат:
{
users: "12,5 тыс.",
downloads: "728 тыс.",
revenue: "15,4 млн"
}
const formatter = Globalize.numberFormatter({
compact: "short",
minimumFractionDigits: 1,
maximumFractionDigits: 2,
useGrouping: false
});
console.log(formatter(1234567));
Результат:
1.23M
Globalize.locale("fr");
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(1500000));
Если необходимые CLDR-данные не подключены, Globalize выбросит исключение.
plurals.jsonКомпактное форматирование зависит от правил множественного числа.
Нужно подключать:
require("cldr-data/supplemental/plurals.json")
require("cldr-data/main/ru/numbers.json")
Без этих данных форматирование работать не будет.
Плохо:
items.forEach(item => {
const formatter = Globalize.numberFormatter({
compact: "short"
});
console.log(formatter(item));
});
Хорошо:
const formatter = Globalize.numberFormatter({
compact: "short"
});
items.forEach(item => {
console.log(formatter(item));
});
Компактное форматирование особенно полезно в:
const compact = Globalize.numberFormatter({
compact: "short"
});
function Stats({ value }) {
return (
<span>{compact(value)}</span>
);
}
const compact = Globalize.numberFormatter({
compact: "short"
});
app.config.globalProperties.$compact = compact;
Компонент:
<span>{{ $compact(2500000) }}</span>
const compact = Globalize.numberFormatter({
compact: "short"
});
console.log(compact(9800000));
Компактное форматирование требует:
Поэтому рекомендуется:
Globalize обычно поддерживает:
| Значение | Английский | Русский |
|---|---|---|
| 1 000 | K | тыс. |
| 1 000 000 | M | млн |
| 1 000 000 000 | B | млрд |
| 1 000 000 000 000 | T | трлн |
Набор сокращений определяется данными CLDR конкретной локали.