Как показывать или скрывать минус для отрицательных чисел?
Управляйте отображением плюса и минуса в форматированных числах для разных случаев
Введение
В разных ситуациях требуется разное отображение отрицательных чисел. На дашборде с изменениями температуры нужны явные плюсы и минусы, чтобы показать направление. В графиках, где важна только величина, знак вообще не нужен. В финансовых отчётах по стандарту бухгалтерии отрицательные суммы заключают в скобки вместо минуса.
API Intl.NumberFormat в JavaScript предоставляет опцию signDisplay для управления отображением знаков у форматированных чисел. Эта опция даёт полный контроль над видимостью знака для отрицательных, положительных чисел и нуля.
Как JavaScript по умолчанию форматирует отрицательные числа
По умолчанию Intl.NumberFormat показывает минус для отрицательных чисел и не показывает знак для положительных.
const formatter = new Intl.NumberFormat('en-US');
formatter.format(-42);
// "-42"
formatter.format(42);
// "42"
formatter.format(0);
// "0"
Это поведение подходит для большинства случаев, но вы можете изменить его, если нужно другое отображение знаков.
Управление отображением знака с помощью опции signDisplay
Опция signDisplay принимает пять значений, которые определяют, когда показывать знаки:
"auto": Показывать знаки только для отрицательных чисел, включая отрицательный ноль (по умолчанию)"never": Никогда не показывать знаки"always": Всегда показывать знаки для положительных и отрицательных чисел"exceptZero": Показывать знаки для положительных и отрицательных чисел, но не для нуля"negative": Показывать знаки только для отрицательных чисел, кроме отрицательного нуля
Передавайте опцию signDisplay в объекте опций при создании форматтера.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'always'
});
Полностью скрыть минус
Используйте signDisplay: 'never', чтобы скрыть все знаки и показывать только абсолютные значения.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'never'
});
formatter.format(-100);
// "100"
formatter.format(100);
// "100"
formatter.format(-0);
// "0"
Эта настройка убирает знак у всех чисел, так что -100 и 100 будут отображаться одинаково. Отрицательный ноль будет отображаться как "0" без знака.
Используйте этот вариант, если показываете величины, где направление не важно, например, абсолютные изменения на графиках, расчёты расстояний или погрешности.
const changes = [-15, 23, -8, 42];
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'never'
});
changes.map(change => formatter.format(change));
// ["15", "23", "8", "42"]
Показывать минус только для отрицательных чисел
Опция signDisplay: 'auto' — это поведение по умолчанию. Она показывает знаки для отрицательных чисел, но не для положительных.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'auto'
});
formatter.format(-100);
// "-100"
formatter.format(100);
// "100"
formatter.format(-0);
// "-0"
Обратите внимание, что отрицательный ноль отображается как "-0" с этой опцией. JavaScript различает положительный и отрицательный ноль, что может встречаться в некоторых математических операциях.
Используйте signDisplay: 'negative', чтобы скрыть знак у отрицательного нуля, но оставить его для других отрицательных чисел.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'negative'
});
formatter.format(-100);
// "-100"
formatter.format(100);
// "100"
formatter.format(-0);
// "0"
Опция negative рассматривает отрицательный ноль как особый случай и форматирует его без знака. Это помогает избежать путаницы там, где различие между положительным и отрицательным нулём не важно для пользователя.
Показывать знаки для всех чисел, кроме нуля
Используйте signDisplay: 'exceptZero', чтобы показывать знаки для положительных и отрицательных чисел, но не показывать знак, если значение ровно ноль.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'exceptZero'
});
formatter.format(-100);
// "-100"
formatter.format(100);
// "+100"
formatter.format(0);
// "0"
formatter.format(-0);
// "0"
Положительные числа отображаются с плюсом. Нули (и положительный, и отрицательный) — без знака.
Этот вариант отлично подходит для отображения изменений или дельт, где ноль означает отсутствие изменений. Показывать "+0" или "-0" было бы запутанно, а вот "0" делает смысл очевидным.
const deltas = [5, -3, 0, -0, 12];
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'exceptZero'
});
deltas.map(delta => formatter.format(delta));
// ["+5", "-3", "0", "0", "+12"]
Показывать знаки для всех чисел
Используйте signDisplay: 'always', чтобы показывать знаки для всех чисел, включая положительные и ноль.
const formatter = new Intl.NumberFormat('en-US', {
signDisplay: 'always'
});
formatter.format(-100);
// "-100"
formatter.format(100);
// "+100"
formatter.format(0);
// "+0"
formatter.format(-0);
// "-0"
Этот параметр добавляет плюс к положительным числам и положительному нулю. Отрицательный ноль остаётся с минусом, чтобы различие было видно.
Используйте этот вариант, если нужно подчеркнуть направление для всех значений, например, при изменениях температуры, высоты или финансовых прибылях и убытках.
const temperatures = [-5, 0, 3, -2];
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
signDisplay: 'always'
});
temperatures.map(temp => formatter.format(temp));
// ["-5°C", "+0°C", "+3°C", "-2°C"]
Комбинируйте отображение знака с форматированием валюты
Опция signDisplay работает со всеми стилями форматирования, включая валюту. В сочетании с currencySign: 'accounting' можно создавать форматы, соответствующие бухгалтерским стандартам.
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencySign: 'accounting'
});
formatter.format(-1234.56);
// "($1,234.56)"
В бухгалтерской записи отрицательные суммы заключаются в скобки вместо использования минуса. Такой подход делает отрицательные числа более заметными в финансовых отчётах.
Можно комбинировать бухгалтерское отображение с разными значениями signDisplay.
const always = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencySign: 'accounting',
signDisplay: 'always'
});
always.format(1234.56);
// "+$1,234.56"
always.format(-1234.56);
// "($1,234.56)"
const never = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencySign: 'accounting',
signDisplay: 'never'
});
never.format(-1234.56);
// "$1,234.56"
С signDisplay: 'always' положительные значения показывают плюс, а отрицательные — по-прежнему в скобках. С signDisplay: 'never' и положительные, и отрицательные значения отображаются без знаков и скобок.
Когда использовать каждый вариант отображения знака
Выбирайте значение signDisplay в зависимости от того, что означают ваши числа и как пользователи будут их воспринимать.
Используйте signDisplay: 'auto' для стандартного форматирования чисел, когда важно явно выделять отрицательные значения. Это вариант по умолчанию, он отлично подходит для цен, количеств, измерений и большинства других случаев.
Используйте signDisplay: 'never', если нужно показывать абсолютные значения или величины, где направление не имеет значения. Это удобно для расчёта расстояний, погрешностей, абсолютных изменений и визуализаций данных, где важна только величина.
Используйте signDisplay: 'negative', если вам нужно стандартное форматирование отрицательных чисел, но при этом не хотите показывать отрицательный ноль. Это помогает избежать запутанных отображений вроде "-0" в математических или научных задачах, где различие между положительным и отрицательным нулём не имеет значения для пользователя.
Используйте signDisplay: 'exceptZero', когда отображаете изменения или дельты, где ноль означает отсутствие изменений. Это делает приросты и потери очевидными и не даёт путаницы с отображением "+0" или "-0". Такой вариант отлично подходит для изменений температуры, движения цен акций и метрик производительности.
Используйте signDisplay: 'always', если важно направление для всех значений и нужно явно выделять как увеличение, так и уменьшение. Изменения температуры, разница высот и финансовые отчёты часто используют такой формат, чтобы положительные и отрицательные значения были одинаково заметны.
// Standard pricing: use auto (default)
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(-50);
// "-$50.00"
// Absolute price difference: use never
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
signDisplay: 'never'
}).format(-50);
// "$50.00"
// Price change: use exceptZero
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
signDisplay: 'exceptZero'
}).format(50);
// "+$50.00"
// Temperature change: use always
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
signDisplay: 'always'
}).format(3);
// "+3°C"
Вариант signDisplay даёт вам точный контроль над тем, как отображаются положительные и отрицательные числа в вашем приложении. Выбирайте тот вариант, который лучше всего доносит смысл до пользователя в зависимости от контекста и назначения каждого числа.