kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Philipp Lenssen
Philipp Lenssen
Вопрос

Преобразование длинного числа в сокращенную строку на JavaScript с особым требованием краткости

На JavaScript как написать функцию, которая преобразует заданное [edit: целое положительное число] число (менее 100 миллиардов) в трехбуквенную аббревиатуру - где 0-9 и a-z/A-Z считаются за букву, а точка (поскольку она такая маленькая во многих пропорциональных шрифтах) - нет, и игнорируется с точки зрения буквенного ограничения?

Этот вопрос связан с этой полезной темой, но это'не одно и то же; например, там, где эта функция выводит, например, "123456 -> 1.23k" ("123.5k" - это 5 букв), я ищу что-то, что делает "123456 -> 0.1m" ("0[.]1m" - это 3 буквы). Например, это будет выход функции hoped (слева исходное, справа идеальное возвращаемое значение):

0                      "0"
12                    "12"
123                  "123"
1234                "1.2k"
12345                "12k"
123456              "0.1m"
1234567             "1.2m"
12345678             "12m"
123456789           "0.1b"
1234567899          "1.2b"
12345678999          "12b"

Спасибо!

Обновление: Спасибо! Ответ получен и работает в соответствии с требованиями при внесении следующих изменений:.

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortValue = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}
58 2012-05-15T11:40:52+00:00 14
 LaurelB
LaurelB
Редактировал вопрос 9-го июля 2019 в 4:38
Программирование
numbers
javascript
Решение / Ответ
 chucktator
chucktator
15-го мая 2012 в 1:05
2012-05-15T13:05:16+00:00
Дополнительно
Источник
Редактировать
#16191751

Мне кажется, что решение ninjagecko'не совсем соответствует желаемому стандарту. Следующая функция соответствует:

function intToString (value) {
    var suffixes = ["", "k", "m", "b","t"];
    var suffixNum = Math.floor((""+value).length/3);
    var shortValue = parseFloat((suffixNum != 0 ? (value / Math.pow(1000,suffixNum)) : value).toPrecision(2));
    if (shortValue % 1 != 0) {
        var shortNum = shortValue.toFixed(1);
    }
    return shortValue+suffixes[suffixNum];
}

Для значений, превышающих 99 триллионов, буква не будет добавлена, что можно легко исправить, добавив в массив 'suffixes'.

Редактировать по Филиппу: Со следующими изменениями он полностью соответствует всем требованиям!

function abbreviateNumber(value) {
    var newValue = value;
    if (value >= 1000) {
        var suffixes = ["", "k", "m", "b","t"];
        var suffixNum = Math.floor( (""+value).length/3 );
        var shortValue = '';
        for (var precision = 2; precision >= 1; precision--) {
            shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
            var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
            if (dotLessShortValue.length <= 2) { break; }
        }
        if (shortValue % 1 != 0)  shortNum = shortValue.toFixed(1);
        newValue = shortValue+suffixes[suffixNum];
    }
    return newValue;
}
Daniel Beck
Daniel Beck
Редактировал ответ 8-го февраля 2017 в 12:40
50
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 D.Deriso
D.Deriso
17-го сентября 2015 в 7:27
2015-09-17T19:27:03+00:00
Дополнительно
Источник
Редактировать
#16191752

Это позволяет работать и с очень большими значениями и является более лаконичным и эффективным.

abbreviate_number = function(num, fixed) {
  if (num === null) { return null; } // terminate early
  if (num === 0) { return '0'; } // terminate early
  fixed = (!fixed || fixed < 0) ? 0 : fixed; // number of decimal places to show
  var b = (num).toPrecision(2).split("e"), // get power
      k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions
      c = k < 1 ? num.toFixed(0 + fixed) : (num / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power
      d = c < 0 ? c : Math.abs(c), // enforce -0 is 0
      e = d + ['', 'K', 'M', 'B', 'T'][k]; // append power
  return e;
}

Результаты:

for(var a='', i=0; i < 14; i++){ 
    a += i; 
    console.log(a, abbreviate_number(parseInt(a),0)); 
    console.log(-a, abbreviate_number(parseInt(-a),0)); 
}

0 0
-0 0
01 1
-1 -1
012 12
-12 -12
0123 123
-123 -123
01234 1.2K
-1234 -1.2K
012345 12.3K
-12345 -12.3K
0123456 123.5K
-123456 -123.5K
01234567 1.2M
-1234567 -1.2M
012345678 12.3M
-12345678 -12.3M
0123456789 123.5M
-123456789 -123.5M
012345678910 12.3B
-12345678910 -12.3B
01234567891011 1.2T
-1234567891011 -1.2T
0123456789101112 123.5T
-123456789101112 -123.5T
012345678910111213 12345.7T
-12345678910111212 -12345.7T
27
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 HoangLong85
HoangLong85
27-го июля 2016 в 5:31
2016-07-27T05:31:16+00:00
Дополнительно
Источник
Редактировать
#16191755

Я думаю, вы не можете попробовать это numeraljs/<БР><БР> Если вы хотите конвертировать 1000 до 1к

console.log(numeral(1000).format('0a'));

и если вы хотите конвертировать 123400 до 123,4 к попробовать этот

console.log(numeral(123400).format('0.0a'));
11
0
 NuSkooler
NuSkooler
9-го сентября 2017 в 7:53
2017-09-09T19:53:12+00:00
Дополнительно
Источник
Редактировать
#16191758

Здесь's то, что я думаю, это довольно элегантное решение. Не пытайтесь бороться с отрицательными числами:

const COUNT_ABBRS = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];

function formatCount(count, withAbbr = false, decimals = 2) {
    const i     = 0 === count ? count : Math.floor(Math.log(count) / Math.log(1000));
    let result  = parseFloat((count / Math.pow(1000, i)).toFixed(decimals));
    if(withAbbr) {
        result += `${COUNT_ABBRS[i]}`; 
    }
    return result;
}

Примеры:

   formatCount(1000, true);
=> '1k'
   formatCount(100, true);
=> '100'
   formatCount(10000, true);
=> '10k'
   formatCount(10241, true);
=> '10.24k'
   formatCount(10241, true, 0);
=> '10k'
   formatCount(10241, true, 1)
=> '10.2k'
   formatCount(1024111, true, 1)
=> '1M'
   formatCount(1024111, true, 2)
=> '1.02M'
8
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 tfmontague
tfmontague
4-го мая 2019 в 10:44
2019-05-04T22:44:18+00:00
Дополнительно
Источник
Редактировать
#16191762

Много ответов по этой теме сложно, используя математические объекты, карта объектов, для петель и т. д. Но эти подходы не'т на самом деле очень сильно усовершенствовать конструкцию - они вводят больше строк кода, больше сложности, больше памяти. После оценки нескольких подходов, я думаю, что ручной подход является самым простым для понимания, и обеспечивает высочайшую производительность.

в

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
  if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
  if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + "B";
  if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
};

console.log(formatCash(1235000));

в

6
0
 ninjagecko
ninjagecko
15-го мая 2012 в 12:27
2012-05-15T12:27:44+00:00
Дополнительно
Источник
Редактировать
#16191750

Судя по моему ответу на https://stackoverflow.com/a/10600491/711085 , ваш ответ на самом деле немного короче в реализации за счет использования .substring(0,3):

function format(n) {
    with (Math) {
        var base = floor(log(abs(n))/log(1000));
        var suffix = 'kmb'[base-1];
        return suffix ? String(n/pow(1000,base)).substring(0,3)+suffix : ''+n;
    }
}

(Как обычно, не используйте Math, если вы не знаете точно, что делаете; присваивание var pow=... и тому подобное приведет к безумным ошибкам. Смотрите ссылку на более безопасный способ).

> tests = [-1001, -1, 0, 1, 2.5, 999, 1234, 
           1234.5, 1000001, Math.pow(10,9), Math.pow(10,12)]
> tests.forEach(function(x){ console.log(x,format(x)) })

-1001 "-1.k"
-1 "-1"
0 "0"
1 "1"
2.5 "2.5"
999 "999"
1234 "1.2k"
1234.5 "1.2k"
1000001 "1.0m"
1000000000 "1b"
1000000000000 "1000000000000"

В случае жесткого требования к 3 символам необходимо отлавливать случай, когда результат равен >=1 триллион, иначе вы рискуете создать искаженные данные, что будет очень плохо.

 Community
Community
Редактировал ответ 23-го мая 2017 в 12:10
6
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 danilowoz
danilowoz
2-го февраля 2018 в 4:37
2018-02-02T16:37:30+00:00
Дополнительно
Источник
Редактировать
#16191759

Код

const SI_PREFIXES = [
  { value: 1, symbol: '' },
  { value: 1e3, symbol: 'k' },
  { value: 1e6, symbol: 'M' },
  { value: 1e9, symbol: 'G' },
  { value: 1e12, symbol: 'T' },
  { value: 1e15, symbol: 'P' },
  { value: 1e18, symbol: 'E' },
]

const abbreviateNumber = (number) => {
  if (number === 0) return number

  const tier = SI_PREFIXES.filter((n) => number >= n.value).pop()
  const numberFixed = (number / tier.value).toFixed(1)

  return `${numberFixed}${tier.symbol}`
}

abbreviateNumber(2000) // "2.0k"
abbreviateNumber(2500) // "2.5k"
abbreviateNumber(255555555) // "255.6M"

Тестов:

import abbreviateNumber from './abbreviate-number'

test('abbreviateNumber', () => {
  expect(abbreviateNumber(0)).toBe('0')
  expect(abbreviateNumber(100)).toBe('100')
  expect(abbreviateNumber(999)).toBe('999')

  expect(abbreviateNumber(1000)).toBe('1.0k')
  expect(abbreviateNumber(100000)).toBe('100.0k')
  expect(abbreviateNumber(1000000)).toBe('1.0M')
  expect(abbreviateNumber(1e6)).toBe('1.0M')
  expect(abbreviateNumber(1e10)).toBe('10.0G')
  expect(abbreviateNumber(1e13)).toBe('10.0T')
  expect(abbreviateNumber(1e16)).toBe('10.0P')
  expect(abbreviateNumber(1e19)).toBe('10.0E')

  expect(abbreviateNumber(1500)).toBe('1.5k')
  expect(abbreviateNumber(1555)).toBe('1.6k')

  expect(abbreviateNumber(undefined)).toBe('0')
  expect(abbreviateNumber(null)).toBe(null)
  expect(abbreviateNumber('100')).toBe('100')
  expect(abbreviateNumber('1000')).toBe('1.0k')
})
 danilowoz
danilowoz
Редактировал ответ 2-го февраля 2018 в 4:53
1
0
 MichaelJones
MichaelJones
29-го марта 2016 в 3:05
2016-03-29T15:05:10+00:00
Дополнительно
Источник
Редактировать
#16191753

После некоторых игры вокруг, этот подход, кажется, отвечают требуемым критериям. Занимает некоторое вдохновение от @chuckator'ы ответ.

function abbreviateNumber(value) {

    if (value <= 1000) {
        return value.toString();
    }

    const numDigits = (""+value).length;
    const suffixIndex = Math.floor(numDigits / 3);

    const normalisedValue = value / Math.pow(1000, suffixIndex);

    let precision = 2;
    if (normalisedValue < 1) {
        precision = 1;
    }

    const suffixes = ["", "k", "m", "b","t"];
    return normalisedValue.toPrecision(precision) + suffixes[suffixIndex];
}
1
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Priyanshu Chauhan
Priyanshu Chauhan
4-го июля 2017 в 3:27
2017-07-04T15:27:20+00:00
Дополнительно
Источник
Редактировать
#16191756

Международный-это стандарт на JavaScript 'пакет' для реализации многоязычных поведения. Международный.NumberFormatter конкретно локализованный количество праматерии. Так что этот код на самом деле уважает свои локально настроенные тысячи и десятичные разделители.

intlFormat(num) {
    return new Intl.NumberFormat().format(Math.round(num*10)/10);
}

abbreviateNumber(value) {
    let num = Math.floor(value);
    if(num >= 1000000000)
        return this.intlFormat(num/1000000000)+'B';
    if(num >= 1000000)
        return this.intlFormat(num/1000000)+'M';
    if(num >= 1000)
        return this.intlFormat(num/1000)+'k';
    return this.intlFormat(num);
}

abbreviateNumber(999999999999) // дает 999B

Вопрос: https://stackoverflow.com/questions/25611937/abbreviate-a-localized-number-in-javascript-for-thousands-1k-and-millions-1m

1
0
 nimeresam
nimeresam
13-го июня 2018 в 10:35
2018-06-13T10:35:22+00:00
Дополнительно
Источник
Редактировать
#16191760

Я'м, используя эту функцию, чтобы получить эти значения.

function Converter(number, fraction) {
    let ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'K' },
      { divider: 1e6, suffix: 'M' },
      { divider: 1e9, suffix: 'G' },
      { divider: 1e12, suffix: 'T' },
      { divider: 1e15, suffix: 'P' },
      { divider: 1e18, suffix: 'E' },
    ]
    //find index based on number of zeros
    let index = (Math.abs(number).toString().length / 3).toFixed(0)
    return (number / ranges[index].divider).toFixed(fraction) + ranges[index].suffix
}

Каждых 3 цифр имеет другой суффикс, что's то, что я'м пытаясь найти во-первых.

Так, удалить негативный символ при наличии, а затем найти, сколько 3 цифры в этом числе.

после чего найти соответствующий суффикс, основанные на предыдущих расчетах добавлены делимого.

Converter(1500, 1)

Вернется:

1.5K
1
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Stefan Gabos
Stefan Gabos
15-го ноября 2019 в 9:47
2019-11-15T21:47:45+00:00
Дополнительно
Источник
Редактировать
#16191763

Здесь'с другой взгляд на это. Я хотел 123456 быть 123.4 K вместо 0,1 м

function convert(value) {
    var length = (value + '').length,
        index = Math.ceil((length - 3) / 3),
        suffix = ['K', 'M', 'B', 'T'];

    if (length < 4) return value;
    return (value / Math.pow(1000, index)).toFixed(1) + suffix[index - 1];
}
0
0
 Ritesh
Ritesh
30-го июня 2016 в 11:31
2016-06-30T11:31:04+00:00
Дополнительно
Источник
Редактировать
#16191754

Я нашел лучшее решение на так вот со скрипкой под управлением примеры Как @chucktator возвращает решение Нана во многих случаях. Он работал отлично для меня.

 Community
Community
Редактировал ответ 23-го мая 2017 в 12:26
0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Pasupol Bunsaen
Pasupol Bunsaen
29-го августа 2017 в 2:24
2017-08-29T02:24:03+00:00
Дополнительно
Источник
Редактировать
#16191757
            function converse_number (labelValue) {

                    // Nine Zeroes for Billions
                    return Math.abs(Number(labelValue)) >= 1.0e+9

                    ? Math.abs(Number(labelValue)) / 1.0e+9 + "B"
                    // Six Zeroes for Millions 
                    : Math.abs(Number(labelValue)) >= 1.0e+6

                    ? Math.abs(Number(labelValue)) / 1.0e+6 + "M"
                    // Three Zeroes for Thousands
                    : Math.abs(Number(labelValue)) >= 1.0e+3

                    ? Math.abs(Number(labelValue)) / 1.0e+3 + "K"

                    : Math.abs(Number(labelValue));

                }

предупреждение(converse_number(100000000000));

0
0
 Rishabh
Rishabh
4-го апреля 2019 в 9:34
2019-04-04T09:34:58+00:00
Дополнительно
Источник
Редактировать
#16191761

@nimesaram

Ваше решение не будет желательным для следующих случае:

Input 50000
Output 50.0k

Следующее решение будет работать нормально.

const convertNumberToShortString = (
  number: number,
  fraction: number
) => {
  let newValue: string = number.toString();
  if (number >= 1000) {
    const ranges = [
      { divider: 1, suffix: '' },
      { divider: 1e3, suffix: 'k' },
      { divider: 1e6, suffix: 'm' },
      { divider: 1e9, suffix: 'b' },
      { divider: 1e12, suffix: 't' },
      { divider: 1e15, suffix: 'p' },
      { divider: 1e18, suffix: 'e' }
    ];
    //find index based on number of zeros
    const index = Math.floor(Math.abs(number).toString().length / 3);
    let numString = (number / ranges[index].divider).toFixed(fraction);
    numString =
      parseInt(numString.substring(numString.indexOf('.') + 1)) === 0
        ? Math.floor(number / ranges[index].divider).toString()
        : numString;
    newValue = numString + ranges[index].suffix;
  }
  return newValue;
};

// Input 50000
// Output 50k
// Input 4500
// Output 4.5k
0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Похожие сообщества 12
JavaScript Jobs — чат
JavaScript Jobs — чат
26 423 пользователей
JavaScript Jobs — чат для поиска работы и людей Правила оформления: @telegram-ru/r1WQe5F1m" rel="nofollow noopener noreferrer" class="text-blue hover:text-black link" target="_blank">https://teletype.in/@telegram-ru/r1WQe5F1m См. также: @mobile_jobs, @devops_jobs, @nodejs_jobs, @react_js, @angular_ru, @js_ru
Открыть telegram
JavaScript Noobs — сообщество новичков
JavaScript Noobs — сообщество новичков
8 998 пользователей
Помогаем друг другу разбираться с JS Правила: @js_noobs_ru/rules" rel="nofollow noopener noreferrer" class="text-blue hover:text-black link" target="_blank">https://teletype.in/@js_noobs_ru/rules Другие полезные чаты — https://github.com/goq/telegram-list или https://rudevs.network/ByKT2JwWQ
Открыть telegram
JavaScript — русскоговорящее сообщество
JavaScript — русскоговорящее сообщество
7 504 пользователей
Рекомендуем сразу отключить уведомления Правила: https://git.io/JycBd См. также: @js_noobs_ru, @nodejs_ru, @ts_cool, @react_js, @electron_cool Вакансии и поиск работы: @javascript_jobs
Открыть telegram
JavaScript.Ninja
JavaScript.Ninja
3 822 пользователей
Правила поведения проекта https://telegra.ph/Kodeks-povedeniya-proekta-JavaScriptNinja-12-15
Открыть telegram
pro.js
pro.js
3 790 пользователей
Сообщество веб (и javascript) разработчиков Чат для начинающих: @js_lib ⚠️ Вакансии - раз в неделю с вилкой зп ⚠️ Оффтоп -> @flood ❌Переход на личности ❌Троллинг ❌Реклама ❌Варез По всем вопросам: @igorz Зам: @slavik4
Открыть telegram
Frontend_ru
Frontend_ru
2 694 пользователей
Русскоговорящее сообщество фронтенд разработчиков Каналы: @frontendnoteschannel @defront Чаты: @bem_ru @javascript_ru @css_ru Важно! http://nometa.xyz
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Александр Македонский
Зарегистрирован 6 дней назад
2
Andrei Kalinin
Зарегистрирован 3 недели назад
3
Koroleva Ego
Зарегистрирован 1 месяц назад
4
Star Lenon
Зарегистрирован 1 месяц назад
5
Данил Жевнеров
Зарегистрирован 2 месяца назад
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
ID
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией