17

I want to convert a number into a string representation with a format similar to Stack Overflow reputation display.

e.g.

  • 999 == '999'
  • 1000 == '1,000'
  • 9999 == '9,999'
  • 10000 == '10k'
  • 10100 == '10.1k'
Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
Sky Sanders
  • 36,396
  • 8
  • 69
  • 90
  • 1
    Possible dupe: http://stackoverflow.com/questions/2134161/format-number-like-stackoverflow-rounded-to-thousands-with-k-suffix – Sani Huttunen Jul 05 '10 at 08:00
  • 1
    @sani JavaScript != C#. last time I checked, anyway. – Sky Sanders Jul 05 '10 at 08:05
  • 2
    If you have international users please remember that the comma as thousand separator and dot as decimal one isn't valid everywhere. Same for the letters to represent thousands, millions, ... Microsoft made a jQuery plugin with some support for that but i don't know if it's complete ( http://weblogs.asp.net/scottgu/archive/2010/06/10/jquery-globalization-plugin-from-microsoft.aspx ) – Julien Roncaglia Jul 05 '10 at 09:07

7 Answers7

28

Another approach that produces exactly the desired output:

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';
}

Check the output results here.

yckart
  • 32,460
  • 9
  • 122
  • 129
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • actually, the toFixed was how i initially had implemented the >=10k but the `replace` made me feel dirty ;-) but the <10k is actually way too obvious for me to have come up with. thanks for that. you get the check, but i get to steal the <10k. – Sky Sanders Jul 05 '10 at 08:27
11

UPDATE: CMS got the check and provides a superior answer. Send any more votes his way.

// 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();
}

Output:

  • getRepString(999) == '999'
  • getRepString(1000) == '1,000'
  • getRepString(9999) == '9,999'
  • getRepString(10000) == '10k'
  • getRepString(10100) == '10.1k'
Sky Sanders
  • 36,396
  • 8
  • 69
  • 90
1

Here is CMS's version in PHP (in case someone needed it, like I did):

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));

Output:

string(3) "999"
string(5) "1,000"
string(5) "9,999"
string(3) "10k"
string(5) "10.1k"
Latheesan
  • 23,247
  • 32
  • 107
  • 201
0
 Handlebars.registerHelper("classNameHere",function(rep) {
    var repString;
       if (rep < 1000)
    {
        repString = rep;
    }
    else if (rep < 10000)
    {
        rep = String(rep);
        r = rep.charAt(0);
        s = rep.substring(1);
        repString =  r + ',' + s;
    }
    else
    {
        repDecimal = Math.round(rep / 100) / 10;
        repString = repDecimal + "k";
    }
       return repString.toString();
   });
-1

divide by 1000 then if result is greater than 1 round the number and concantenate a "k" on the end.

If the result is less than 1 just output the actual result!

liamfriel
  • 107
  • 1
  • 11
  • if the number is less than 10000, it should be formatted with a separator, if greater, it should be formatted with a kilo indicator and 1 decimal place, if necessary. you are missing some of the details, liam. – Sky Sanders Jul 05 '10 at 09:29
-1
// 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;
}

This worked for me. I hope, this will help you. Thanks for asking this question.

Kamlesh
  • 5,233
  • 39
  • 50
-2

I created an npm (and bower) module to do this:

npm install --save approximate-number

Usage:

var approx = require('approximate-number');
approx(123456); // "123k" 
Nathan Friedly
  • 7,837
  • 3
  • 42
  • 59