Мне нужно показать значение валюты в формате 1K, равное одной тысяча, или 1,1K, 1.2K, 1.9K и т.д., если оно не равно тысячам, в противном случае, если менее тысячи, отобразите нормальный 500, 100, 250 и т.д., Используя javascript для форматирования номера?
Отформатируйте число как 2.5K, если тысяча или больше, иначе 900
Ответ 1
Похоже, это должно работать для вас:
function kFormatter(num) {
    return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)
}
    
console.log(kFormatter(1200)); // 1.2k
console.log(kFormatter(-1200)); // -1.2k
console.log(kFormatter(900)); // 900
console.log(kFormatter(-900)); // -900		Ответ 2
Более обобщенная версия:
function nFormatter(num, digits) {
  var si = [
    { 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" }
  ];
  var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  var i;
  for (i = si.length - 1; i > 0; i--) {
    if (num >= si[i].value) {
      break;
    }
  }
  return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}
/*
 * Tests
 */
var tests = [
  { num: 1234, digits: 1 },
  { num: 100000000, digits: 1 },
  { num: 299792458, digits: 1 },
  { num: 759878, digits: 1 },
  { num: 759878, digits: 0 },
  { num: 123, digits: 1 },
  { num: 123.456, digits: 1 },
  { num: 123.456, digits: 2 },
  { num: 123.456, digits: 4 }
];
var i;
for (i = 0; i < tests.length; i++) {
  console.log("nFormatter(" + tests[i].num + ", " + tests[i].digits + ") = " + nFormatter(tests[i].num, tests[i].digits));
}		Ответ 3
Дальнейшее улучшение Salman Answer, потому что он возвращает nFormatter (33000) как 33.0K
function nFormatter(num) {
     if (num >= 1000000000) {
        return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
     }
     if (num >= 1000000) {
        return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
     }
     if (num >= 1000) {
        return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
     }
     return num;
}
теперь nFormatter (33000) = 33K
Ответ 4
 Здесь простое решение, которое позволяет избежать всех операторов if (с силой Math).
var SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"];
function abbreviateNumber(number){
    // what tier? (determines SI symbol)
    var tier = Math.log10(number) / 3 | 0;
    // if zero, we don't need a suffix
    if(tier == 0) return number;
    // get suffix and determine scale
    var suffix = SI_SYMBOL[tier];
    var scale = Math.pow(10, tier * 3);
    // scale the number
    var scaled = number / scale;
    // format number and add suffix
    return scaled.toFixed(1) + suffix;
}
 Бонус Мем
Ответ 5
/**
 * Shorten number to thousands, millions, billions, etc.
 * http://en.wikipedia.org/wiki/Metric_prefix
 *
 * @param {number} num Number to shorten.
 * @param {number} [digits=0] The number of digits to appear after the decimal point.
 * @returns {string|number}
 *
 * @example
 * // returns '12.5k'
 * shortenLargeNumber(12543, 1)
 *
 * @example
 * // returns '-13k'
 * shortenLargeNumber(-12567)
 *
 * @example
 * // returns '51M'
 * shortenLargeNumber(51000000)
 *
 * @example
 * // returns 651
 * shortenLargeNumber(651)
 *
 * @example
 * // returns 0.12345
 * shortenLargeNumber(0.12345)
 */
function shortenLargeNumber(num, digits) {
    var units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
        decimal;
    for(var i=units.length-1; i>=0; i--) {
        decimal = Math.pow(1000, i+1);
        if(num <= -decimal || num >= decimal) {
            return +(num / decimal).toFixed(digits) + units[i];
        }
    }
    return num;
}
спасибо @Cos для комментариев, я удалил зависимость Math.round10.
Ответ 6
Дайте кредит Waylon Flinn, если вам это нравится
Это было улучшено из его более элегантного подхода для обработки отрицательных чисел и случая ".0".
Чем меньше циклов и случаев "если" у вас есть, тем лучше IMO.
function abbreviateNumber(number) {
    var SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"];
    var tier = Math.log10(Math.abs(number)) / 3 | 0;
    if(tier == 0) return number;
    var postfix = SI_POSTFIXES[tier];
    var scale = Math.pow(10, tier * 3);
    var scaled = number / scale;
    var formatted = scaled.toFixed(1) + '';
    if (/\.0$/.test(formatted))
      formatted = formatted.substr(0, formatted.length - 2);
    return formatted + postfix;
}
jsFiddle с тестовыми примерами → https://jsfiddle.net/xyug4nvz/7/
Ответ 7
это довольно элегантно.
function formatToUnits(number, precision) {
  const abbrev = ['', 'k', 'm', 'b', 't'];
  const unrangifiedOrder = Math.floor(Math.log10(Math.abs(number)) / 3)
  const order = Math.max(0, Math.min(unrangifiedOrder, abbrev.length -1 ))
  const suffix = abbrev[order];
  return (number / Math.pow(10, order * 3)).toFixed(precision) + suffix;
}
formatToUnits(12345, 2)
==> "12.35k"
formatToUnits(0, 3)
==> "0.000"
		Ответ 8
Многие ответы в этом потоке становятся довольно сложными, используя объекты Math, объекты карты, циклы for, регулярные выражения и т.д. Но эти подходы на самом деле не улучшают читаемость кода или производительность. Прямой подход, кажется, предлагает лучший дизайн.
Форматирование денежного значения с помощью K
const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3) return +(n / 1e3).toFixed(1) + "K";
};
console.log(formatCash(2500));		Ответ 9
Дальнейшее улучшение ответа @Yash с поддержкой отрицательного числа:
function nFormatter(num) {
    isNegative = false
    if (num < 0) {
        isNegative = true
    }
    num = Math.abs(num)
    if (num >= 1000000000) {
        formattedNumber = (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
    } else if (num >= 1000000) {
        formattedNumber =  (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
    } else  if (num >= 1000) {
        formattedNumber =  (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
    } else {
        formattedNumber = num;
    }   
    if(isNegative) { formattedNumber = '-' + formattedNumber }
    return formattedNumber;
}
nFormatter(-120000)
"-120K"
nFormatter(120000)
"120K"
		Ответ 10
Вы можете использовать пакет d3-format, смоделированный после форматирования форматированных строк Python PEP3101:
var f = require('d3-format')
console.log(f.format('.2s')(2500)) // displays "2.5k"
		Ответ 11
Этот пост довольно старый, но я как-то добрался до этого поста, ища что-то. SO, чтобы добавить мой ввод. Numeral js - это одностановичное решение в настоящее время через несколько дней. Он дает большое количество методов, помогающих форматировать числа
Ответ 12
Добавление верхнего ответа, это даст 1k для 1000 вместо 1.0k
function kFormatter(num) {
    return num > 999 ? num % 1000 === 0 ? (num/1000).toFixed(0) + 'k' : (num/1000).toFixed(1) + 'k' : num
}
		Ответ 13
- Поддержка отрицательного числа
 -  Проверка на 
!Number.isFinite -  Измените 
' KMGTPEZ Y'на' K M'если вы хотите, чтобы максимальная единица былаM 
Ниже код 1K = 1024, если вы хотите 1K = 1000, измените все 1024 на 1000.
Number.prototype.prefix = function (precision = 2) {
    var units = ' K M G T P E Z Y'.split(' ');
    if (this < 0) {
        return '-' + Math.abs(this).prefix(precision);
    }
    if (this < 1) {
        return this + units[0];
    }
    var power = Math.min(
        Math.floor(Math.log(this) / Math.log(1024)),
        units.length - 1
    );
    return (this / Math.pow(1024, power)).toFixed(precision) + units[power];
}
console.log('10240 = ' + (10240).prefix()) // 10.00K
console.log('1234000 = ' + (1234000).prefix(1)) // 1.2M
console.log('10000 = ' + (-10000).prefix()) // -9.77K		Ответ 14
Улучшение ответа @tfmontague для форматирования десятичных знаков. 33.0к до 33к
largeNumberFormatter(value: number): any {
   let result: any = value;
   if (value >= 1e3 && value < 1e6) { result = (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K'; }
   if (value >= 1e6 && value < 1e9) { result = (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'; }
   if (value >= 1e9) { result = (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'T'; }
   return result;
}
		Ответ 15
/*including negative values*/    
function nFormatter(num) {
      let neg = false;
       if(num < 0){
         num = num * -1;
         neg = true;
       }
       if (num >= 1000000000) {
         if(neg){
           return -1 * (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';  
         }
         return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
       }
       if (num >= 1000000) {
         if(neg){
           return -1 * (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';  
         }
         return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
       }
       if (num >= 1000) {
         if(neg){
           return -1 * (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';  
         }
         return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
       }
       return num;
    }
		Ответ 16
Модифицированная версия ответа Waylon Flinn с поддержкой отрицательных показателей:
function metric(number) {
  const SI_SYMBOL = [
    ["", "k", "M", "G", "T", "P", "E"], // +
    ["", "m", "μ", "n", "p", "f", "a"] // -
  ];
  const tier = Math.floor(Math.log10(Math.abs(number)) / 3) | 0;
  const n = tier < 0 ? 1 : 0;
  const t = Math.abs(tier);
  const scale = Math.pow(10, tier * 3);
  return {
    number: number,
    symbol: SI_SYMBOL[n][t],
    scale: scale,
    scaled: number / scale
  }
}
function metric_suffix(number, precision) {
  const m = metric(number);
  return (typeof precision === 'number' ? m.scaled.toFixed(precision) : m.scaled) + m.symbol;
}
for (var i = 1e-6, s = 1; i < 1e7; i *= 10, s *= -1) {
  // toggles sign in each iteration
  console.log(metric_suffix(s * (i + i / 5), 1));
}
console.log(metric(0));		Ответ 17
Эта функция может преобразовать огромные числа (как положительные, так и отрицательные) в удобный для чтения формат без потери точности:
function abbrNum(n) {
    if (!n || (n && typeof n !== 'number')) {
      return '';
    }
    const ranges = [
      { divider: 1e12 , suffix: 't' },
      { divider: 1e9 , suffix: 'b' },
      { divider: 1e6 , suffix: 'm' },
      { divider: 1e3 , suffix: 'k' }
    ];
    const range = ranges.find(r => Math.abs(n) >= r.divider);
    if (range) {
      return (n / range.divider).toString() + range.suffix;
    }
    return n.toString();
}
/* test cases */
let testAry = [99, 1200, -150000, 9000000];
let resultAry = testAry.map(abbrNum);
console.log("result array: " + resultAry);		Ответ 18
 Я использую эту функцию. Это работает как для php и для javascript.
    /**
     * @param $n
     * @return string
     * Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc
     */
 function num_format($n) {
        $n_format = null;
        $suffix = null;
        if ($n > 0 && $n < 1000) {
           $n_format = Math.floor($n);   
            $suffix = '';
        }
        else if ($n == 1000) {
            $n_format = Math.floor($n / 1000);   //For PHP only use floor function insted of Math.floor()
            $suffix = 'K';
        }
        else if ($n > 1000 && $n < 1000000) {
            $n_format = Math.floor($n / 1000);
            $suffix = 'K+';
        } else if ($n == 1000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M';
        } else if ($n > 1000000 && $n < 1000000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M+';
        } else if ($n == 1000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B';
        } else if ($n > 1000000000 && $n < 1000000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B+';
        } else if ($n == 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T';
        } else if ($n >= 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T+';
        }
       /***** For PHP  ******/
       //  return !empty($n_format . $suffix) ? $n_format . $suffix : 0;
       /***** For Javascript ******/
        return ($n_format + $suffix).length > 0 ? $n_format + $suffix : 0;
    }
		Ответ 19
Я решил подробно рассказать об ответе @Novellizator, чтобы удовлетворить мои потребности. Я хотел гибкую функцию, чтобы справиться с большинством моих потребностей форматирования без внешних библиотек.
Характеристики
-  Возможность использовать суффиксы заказа (k, M и т.д.) 
- Возможность указать собственный список суффиксов заказа для использования
 - Возможность ограничения минимального и максимального порядка
 
 - Контроль количества десятичных знаков
 - Автоматическое разделение запятых
 - Необязательное процентное или долларовое форматирование
 - Контроль над тем, что возвращать в случае нечислового ввода
 - Работает на отрицательных и бесконечных числах
 
Примеры
let x = 1234567.8;
formatNumber(x);  // '1,234,568'
formatNumber(x, {useOrderSuffix: true});  // '1M'
formatNumber(x, {useOrderSuffix: true, decimals: 3, maxOrder: 1});  // '1,234.568k'
formatNumber(x, {decimals: 2, style: '$'});  // '$1,234,567.80'
x = 10.615;
formatNumber(x, {style: '%'});  // '1,062%'
formatNumber(x, {useOrderSuffix: true, decimals: 1, style: '%'});  // '1.1k%'
formatNumber(x, {useOrderSuffix: true, decimals: 5, style: '%', minOrder: 2});  // '0.00106M%'
formatNumber(-Infinity);  // '-∞'
formatNumber(NaN);  // ''
formatNumber(NaN, {valueIfNaN: NaN});  // NaN
 функция
/*
 * Return the given number as a formatted string.  The default format is a plain
 * integer with thousands-separator commas.  The optional parameters facilitate
 * other formats:
 *   - decimals = the number of decimals places to round to and show
 *   - valueIfNaN = the value to show for non-numeric input
 *   - style
 *     - '%': multiplies by 100 and appends a percent symbol
 *     - '$': prepends a dollar sign
 *   - useOrderSuffix = whether to use suffixes like k for 1,000, etc.
 *   - orderSuffixes = the list of suffixes to use
 *   - minOrder and maxOrder allow the order to be constrained.  Examples:
 *     - minOrder = 1 means the k suffix should be used for numbers < 1,000
 *     - maxOrder = 1 means the k suffix should be used for numbers >= 1,000,000
 */
function formatNumber(number, {
    decimals = 0,
    valueIfNaN = '',
    style = '',
    useOrderSuffix = false,
    orderSuffixes = ['', 'k', 'M', 'B', 'T'],
    minOrder = 0,
    maxOrder = Infinity
  } = {}) {
  let x = parseFloat(number);
  if (isNaN(x))
    return valueIfNaN;
  if (style === '%')
    x *= 100.0;
  let order;
  if (!isFinite(x) || !useOrderSuffix)
    order = 0;
  else if (minOrder === maxOrder)
    order = minOrder;
  else {
    const unboundedOrder = Math.floor(Math.log10(Math.abs(x)) / 3);
    order = Math.max(
      0,
      minOrder,
      Math.min(unboundedOrder, maxOrder, orderSuffixes.length - 1)
    );
  }
  const orderSuffix = orderSuffixes[order];
  if (order !== 0)
    x /= Math.pow(10, order * 3);
  return (style === '$' ? '$' : '') +
    x.toLocaleString(
      'en-US',
      {
        style: 'decimal',
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals
      }
    ) +
    orderSuffix +
    (style === '%' ? '%' : '');
}
		Ответ 20
Вау, здесь так много ответов. Я подумал, что расскажу вам, как я решил эту проблему, так как она кажется самой легкой для чтения, обрабатывает отрицательные числа и выходит далеко в диапазоне килограммов для JavaScript. Также было бы легко изменить то, что вы хотите, или расширить еще дальше.
const symbols = [
  { 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' }
];
function numberFormatter(num, digits) {
  const numToCheck = Math.abs(num);
  for (let i = symbols.length - 1; i >= 0; i--) {
    if (numToCheck >= symbols[i].value) {
      const newNumber = (num / symbols[i].value).toFixed(digits);
      return '${newNumber}${symbols[i].symbol}';
    }
  }
  return '0';
}
const tests = [
  { num: 1234, digits: 1 },
  { num: 100000000, digits: 1 },
  { num: 299792458, digits: 1 },
  { num: 759878, digits: 1 },
  { num: -759878, digits: 0 },
  { num: 123, digits: 1 },
  { num: 123.456, digits: 1 },
  { num: -123.456, digits: 2 },
  { num: 123.456, digits: 4 }
];
for (let i = 0; i < tests.length; i++) {
  console.log('numberFormatter(${tests[i].num}, ${tests[i].digits})=${numberFormatter(tests[i].num, tests[i].digits)}');
}		Ответ 21
Не устраивает ни одно из опубликованных решений, поэтому здесь моя версия:
- Поддерживает положительные и отрицательные числа
 - Поддерживает отрицательные показатели
 - По возможности округляет до следующего показателя
 - Выполняет проверку границ (не выдает ошибки для очень больших/маленьких чисел)
 - Снимает конечные нули/пробелы
 Поддерживает параметр точности
function abbreviateNumber(number,digits=2) { var expK = Math.floor(Math.log10(Math.abs(number)) / 3); var scaled = number / Math.pow(1000, expK); if(Math.abs(scaled.toFixed(digits))>=1000) { // Check for rounding to next exponent scaled /= 1000; expK += 1; } var SI_SYMBOLS = "apμm kMGTPE"; var BASE0_OFFSET = SI_SYMBOLS.indexOf(' '); if (expK + BASE0_OFFSET>=SI_SYMBOLS.length) { // Bound check expK = SI_SYMBOLS.length-1 - BASE0_OFFSET; scaled = number / Math.pow(1000, expK); } else if (expK + BASE0_OFFSET < 0) return 0; // Too small return scaled.toFixed(digits).replace(/(\.|(\..*?))0+$/,'$2') + SI_SYMBOLS[expK+BASE0_OFFSET].trim(); } ////////////////// const tests = [ [0.0000000000001,2], [0.00000000001,2], [0.000000001,2], [0.000001,2], [0.001,2], [0.0016,2], [-0.0016,2], [0.01,2], [1,2], [999.99,2], [999.99,1], [-999.99,1], [999999,2], [999999999999,2], [999999999999999999,2], [99999999999999999999,2], ]; for (var i = 0; i < tests.length; i++) { console.log(abbreviateNumber(tests[i][0], tests[i][1]) ); }