Как форматировать числа аналогично формату репутации Stack Overflow

Я хочу преобразовать число в строковое представление в формате, аналогичном отображению репутации Stack Overflow.

e.g.

  • 999 == '999'
  • 1000 == '1,000'
  • 9999 == '9,999'
  • 10000 == '10k'
  • 10100 == '10.1k'

person Sky Sanders    schedule 05.07.2010    source источник
comment
Возможный обман: stackoverflow.com/questions/2134161/   -  person Sani Singh Huttunen    schedule 05.07.2010
comment
@sani JavaScript! = C #. Во всяком случае, в последний раз проверял.   -  person Sky Sanders    schedule 05.07.2010
comment
Если у вас есть международные пользователи, помните, что запятая как разделитель тысяч и точка как десятичная не действительны везде. То же самое для букв, обозначающих тысячи, миллионы, ... Microsoft создала плагин jQuery с некоторой поддержкой для этого, но я не знаю, завершен ли он (weblogs.asp.net/scottgu/archive/2010/06/10/)   -  person Julien Roncaglia    schedule 05.07.2010


Ответы (8)


Другой подход, который дает именно желаемый результат:

function getRepString (rep) {
  rep = rep+''; // coerce to string
  if (rep < 1000) {
    return rep; // return the same number
  }
  if (rep < 10000) { // place a comma between
    return rep.charAt(0) + ',' + rep.substring(1);
  }
  // divide and format
  return (rep/1000).toFixed(rep % 1000 != 0)+'k';
}

Проверьте результаты вывода здесь.

person Christian C. Salvadó    schedule 05.07.2010
comment
на самом деле, toFixed был тем, как я изначально реализовал ›= 10k, но replace заставил меня почувствовать себя грязным ;-), но‹ 10k на самом деле слишком очевиден для меня, чтобы придумать. Спасибо за это. Вы получаете чек, но я могу украсть ‹10k. - person Sky Sanders; 05.07.2010

ОБНОВЛЕНИЕ: CMS прошла проверку и дает превосходный ответ. Присылайте больше голосов к нему.

// formats a number similar to the way stack exchange sites 
// format reputation. e.g.
// for numbers< 10000 the output is '9,999'
// for numbers > 10000 the output is '10k' with one decimal place when needed
function getRepString(rep)
{
    var repString;

    if (rep < 1000)
    {
        repString = rep;
    }
    else if (rep < 10000)
    {
        // removed my rube goldberg contraption and lifted
        // CMS version of this segment
        repString = rep.charAt(0) + ',' + rep.substring(1);
    }
    else
    {
        repString = (Math.round((rep / 1000) * 10) / 10) + "k"
    }

    return repString.toString();
}

Вывод:

  • getRepString(999) == '999'
  • getRepString(1000) == '1,000'
  • getRepString(9999) == '9,999'
  • getRepString(10000) == '10k'
  • getRepString(10100) == '10.1k'
person Sky Sanders    schedule 05.07.2010

Вот функция PHP, которая является частью iZend - http://www.izend.org/en/manual/library/countformat:

function count_format($n, $point='.', $sep=',') {
    if ($n < 0) {
        return 0;
    }

    if ($n < 10000) {
        return number_format($n, 0, $point, $sep);
    }

    $d = $n < 1000000 ? 1000 : 1000000;

    $f = round($n / $d, 1);

    return number_format($f, $f - intval($f) ? 1 : 0, $point, $sep) . ($d == 1000 ? 'k' : 'M');
}
person frasq    schedule 19.06.2012

Вот версия CMS CMS на PHP (на случай, если кому-то это понадобится, как я):

function getRepString($rep) {
    $rep = intval($rep);
    if ($rep < 1000) {
        return (string)$rep;
    }
    if ($rep < 10000) {
        return number_format($rep);
    }
    return number_format(($rep / 1000), ($rep % 1000 != 0)) . 'k';
}

// TEST
var_dump(getRepString(999));
var_dump(getRepString(1000));
var_dump(getRepString(9999));
var_dump(getRepString(10000));
var_dump(getRepString(10100));

Вывод:

string(3) "999"
string(5) "1,000"
string(5) "9,999"
string(3) "10k"
string(5) "10.1k"
person Latheesan    schedule 21.10.2017

// Shortens a number and attaches K, M, B, etc. accordingly
function number_shorten($number, $precision = 3, $divisors = null) {

    // Setup default $divisors if not provided
    if (!isset($divisors)) {
        $divisors = array(
            pow(1000, 0) => '', // 1000^0 == 1
            pow(1000, 1) => 'K', // Thousand
            pow(1000, 2) => 'M', // Million
            pow(1000, 3) => 'B', // Billion
            pow(1000, 4) => 'T', // Trillion
            pow(1000, 5) => 'Qa', // Quadrillion
            pow(1000, 6) => 'Qi', // Quintillion
        );    
    }

    // Loop through each $divisor and find the
    // lowest amount that matches
    foreach ($divisors as $divisor => $shorthand) {
        if (abs($number) < ($divisor * 1000)) {
            // We found a match!
            break;
        }
    }

    // We found our match, or there were no matches.
    // Either way, use the last defined value for $divisor.
    return number_format($number / $divisor, $precision) . $shorthand;
}

Это сработало для меня. Я надеюсь, что это поможет вам. Спасибо, что задали этот вопрос.

person Kamlesh    schedule 02.12.2019

разделите на 1000, тогда, если результат больше 1, округлите число и доведите до конца букву «k».

Если результат меньше 1, просто выведите фактический результат!

person liamfriel    schedule 05.07.2010
comment
если число меньше 10000, оно должно быть отформатировано с помощью разделителя, если больше, оно должно быть отформатировано с указанием килограмма и 1 десятичного знака, если необходимо. тебе не хватает некоторых деталей, Лиам. - person Sky Sanders; 05.07.2010

Я создал npmbower) для этого:

npm install --save approximate-number

Использование:

var approx = require('approximate-number');
approx(123456); // "123k" 
person Nathan Friedly    schedule 06.11.2014

person    schedule
comment
Если вы используете руль, просто используйте это ... это идеальный код в javascript. - person user3170614; 08.01.2014