Take the 2-minute tour ×
Stack Apps is a question and answer site for apps, scripts, and development with the Stack Exchange API. It's 100% free, no registration required.

UPDATE

For JavaScript, see CMS's implementation below. It is much more elegant than the one I provide in the body of this Q.


// 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)
    {
        var mod = rep % 1000;

        repString = ((rep - mod) / 1000)
        + ","
        + ('000' + mod.toString()).slice(-3);
    }
    else
    {
        repString = (rep / 1000).toFixed(1).replace(".0", "") + "k";
    }

    return repString.toString();
}

Output:

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

Post an implementation in the language of your choice.

share|improve this question
    
a more elegant implementation is heading our way... i hope. –  Sky Sanders Jul 5 '10 at 9:24
    
You mean one that we don't have to manually do? Surely thats the whole point of giving us the "raw" score? We can format it how we like. –  JonB Jul 5 '10 at 10:20
    
@jonb - no, i mean that someone showed me a more elegant way to do this and i encouraged him to post it here and hope he does, otherwise I am going to have to post it myself. and, yes, raw data is appropriate for an api return, but i as well as others, in various languages, wish to present this information in a more friendly format. that is what this post is about. –  Sky Sanders Jul 5 '10 at 15:50
    
It looks like most of the implementations here are slightly off. Numbers like 10999 would show as 11k. Also 12452 would be 12.5k. SO rounds up. –  jjnguy Aug 14 '10 at 22:14
    
@jjn - so what you are saying is that the examples shown truncate instead of round up as SO does? I can't speak for any but stackapps.com/questions/1012/… which performs as desired. –  Sky Sanders Aug 14 '10 at 22:37
    
@Code, Yeah. I didn't test out any of them, but it looks liek a bunch of them truncate instead of rounding. –  jjnguy Aug 14 '10 at 23:03
add comment

8 Answers 8

Here you go, another JavaScript approach, originally posted on SO:

function getRepString (rep) {

  rep = rep+''; // coerce to string

  if (rep < 1000) { // return the same number
    return rep; 
  }

  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.

share|improve this answer
3  
+ for you. this is the way to do it in JS. I have removed the JS tag, so there is no 'right' answer now, just an x-language implementation free for all. Thanks for schooling me. –  Sky Sanders Jul 5 '10 at 17:00
    
Using this one now, had a convoluted algorithm for the rep < 10000 case. –  Igor Zevaka Jul 7 '10 at 2:39
add comment

Objective-C:

This should work on iOS 3.2, iOS 4.0 and Mac OS X 10.4 - 10.6 :

I don't have multiple returns because I like a single exit point in my code. Hence I use my trusty friend returnable.

- (NSString*) stringForReputationFormatted:(NSNumber*)reputation
{
    NSString *returnable = nil;
    long rep = [reputation longValue];
    NSString *returnable = nil;

    if (rep < 1000) {
        returnable = [reputation stringValue];
    }
    else if (rep < 10000) {
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
        returnable = [numberFormatter stringForObjectValue:reputation];
        [numberFormatter release];
    }
    else {
        NSString *repStr    = [reputation stringValue];
        NSString *whole     = [repStr substringToIndex:[repStr length]-3];
        NSString *decimal   = [repStr substringWithRange:NSMakeRange([repStr length]-3, 1)];
        if ([decimal intValue] != 0) {
            returnable = [whole stringByAppendingFormat:@".%@K", decimal];
        } else {
            returnable = [whole stringByAppendingFormat:@"K"];
        }
    }
    return returnable;
}

Edit: Apologies for the code being so long. NSDateFormatter isn't working right on iOS atm, so I needed to format the string manually.

Tests to confirm:

Raw:-1 Converted:-1
Raw:0 Converted:0
Raw:1 Converted:1
Raw:2 Converted:2
Raw:10 Converted:10
Raw:100 Converted:100
Raw:101 Converted:101
Raw:999 Converted:999
Raw:1000 Converted:1,000
Raw:1001 Converted:1,001
Raw:3500 Converted:3,500
Raw:6790 Converted:6,790
Raw:8900 Converted:8,900
Raw:9999 Converted:9,999
Raw:10000 Converted:10K
Raw:10099 Converted:10K
Raw:10500 Converted:10.5K
Raw:11600 Converted:11.6K
Raw:10799 Converted:10.7K
Raw:99899 Converted:99.8K
Raw:195999 Converted:195.9K
share|improve this answer
1  
Thanks for that. here, let me buy you some points.... –  Sky Sanders Aug 14 '10 at 22:06
    
@code poet: gracious! –  Brock Woolf Aug 14 '10 at 22:08
    
Well, this isn't 100% the same as SO. Raw:10799 Converted:10.7K should actually be 10.8K. SO rounds up. –  jjnguy Aug 14 '10 at 22:13
    
@jinguy: Looks like i'm not the only one rounding down though. Do you have a link as to where it says it rounds up? –  Brock Woolf Aug 14 '10 at 22:15
1  
@Brock, no. I believe everyone does it wrong. Everyone is simply truncating. It really doesn't matter that much though... –  jjnguy Aug 14 '10 at 22:18
    
See this example: stackoverflow.com/users/21632/adam-bellaire –  jjnguy Aug 14 '10 at 22:19
    
@jinguy: Okay, well I thought you shouldn't be displaying for example: 10K UNTIL you have actually reached it. Seems like a false reading to round up. –  Brock Woolf Aug 14 '10 at 22:21
    
@Brock, I believe 9999 does show as 9,999. It's just when you get into th2 5 digits that the rounding kicks in. –  jjnguy Aug 14 '10 at 22:22
    
@jinguy: Fair enough, I'm going to round down for my SO app though :) –  Brock Woolf Aug 14 '10 at 22:25
    
@brock, yeah. I would do it the easy way too. That's how we do it in StackWrap4J. –  jjnguy Aug 14 '10 at 22:27
    
stackapps.com/questions/1012/… rounds up as expected. –  Sky Sanders Aug 14 '10 at 23:02
add comment

Here's a Java implementation using NumberFormat.

public static void main(String[] args) {

    int[] values = { 999, 1000, 9999, 10000, 10100 };

    for( int rep : values ) {
        System.out.println( formatRep(rep) );
    }
}

public static String formatRep(int rep) {
    if(rep < 1000) {
        return rep + "";
    }
    if(rep < 10000) {
        NumberFormat formatter = new DecimalFormat("#,###");
        return formatter.format(rep);
    }
    else {
        NumberFormat formatter = new DecimalFormat("#,###.#k");
        double d = rep / 1000.0;
        return formatter.format(d);
    }
}

Output:

999
1,000
9,999
10k
10.1k

I'm not sure about that last format for numbers greater than 999k. I guess we have a few years to wait and see. :)

share|improve this answer
2  
++ proxy thanks from java dudes, which i am not. –  Sky Sanders Jul 6 '10 at 16:03
add comment

c#

Rounds up - same same SO.

public string FormatReputation(int value)
{
    var rep = System.Convert.ToDouble(value);

    if (rep < 10000)
    {
        return rep.ToString("N0");
    }

    return (rep / 1000)
         .ToString(rep % 1000 == 0 ? "" : "F1") + 'k';
}
  • 100 => "100"
  • 1200 => "1,200"
  • 9999 => "9,999"
  • 10000 => "10k"
  • 10200 => "10.2k"

confirmation as per jjng's comment

  • 10999 => "11k"
  • 12452 => "12.5k"
share|improve this answer
add comment

Here's a quick and dirty way of how I did mine in .NET

Visual Basic

    Public Shared Function GetReputation(ByVal input As Integer) As String

        Dim _input As String = input.ToString
        Select Case input
            Case Is > 99999 : Return _input.Remove(_input.Length - 3) & "k"
            Case Is > 9999 : Return Math.Round(Double.Parse(input / 1000), 1).ToString & "k"
            Case Is > 999 : Return String.Format("{0:N0}", input)
            Case Else : Return _input
        End Select
    End Function
share|improve this answer
1  
+ this is what I would like to see - implementations in various languages. thanks –  Sky Sanders Jul 5 '10 at 15:50
add comment

Just for completeness, here is the C# version I am using ported from the VB version given by @rockinthesixstring:

private string FormatReputation(int reputation)
{
     string s = reputation.ToString();
     if (reputation > 99999)
         return s.Remove(s.Length - 3) + "k";
     else if (reputation > 9999)
         return Math.Round((double)reputation / (double)1000, 1).ToString() + "k";
     else if (reputation > 999)
         return String.Format("{0:N0}", reputation);
     return s;
}
share|improve this answer
    
+ thanks for contributing. –  Sky Sanders Jul 10 '10 at 19:38
add comment

These are great feature ideas - thanks for the tips!

I've more or less converted CMS' answer to Python:

class FormattedReputation(int):
    def format(rep):
        """Formats the reputation score like it is formatted on the sites. Heavily based on CMS' JavaScript implementation at
        http://stackapps.com/questions/1012/how-to-format-reputation-numbers-similar-to-stack-exchange-sites/1019#1019"""
        str_rep = str(rep)

        if rep < 1000:
            return str_rep
        elif rep < 10000:
            return '%s,%s' % (str_rep[0], str_rep[1:])
        elif rep % 1000 == 0:
            return '%dk' % (rep / 1000.0)
        else:
            return '%.1fk' % (rep / 1000.0)

This is used automatically as an alternative to int for reputation fields in Py-StackExchange, so using it on its own is slightly awkward:

lucas@ubuntu:~/projects/py-stackexchange$ python -i se_inter.py
>>> FormattedReputation(100).format()
'100'
>>> FormattedReputation(1000).format()
'1,000'
>>> FormattedReputation(1240).format()
'1,240'
>>> FormattedReputation(12403).format()
'12.4k'
>>> FormattedReputation(100000).format()
'100k'
share|improve this answer
    
Thanks for that. you might include some test runs, both for your edification and others. –  Sky Sanders Aug 14 '10 at 22:07
    
Do you mean like that? –  Lucas Jones Aug 14 '10 at 23:26
add comment

Good ole' PHP:

// Any number larger than 1000 gets returned like '4.5k'

function Numberify($num)
{
    if($num > 1000)
        return (floor($num / 100) / 10) . 'k';
    return $num
}

Do you like the name of the function? :)

share|improve this answer
    
+ thanks for contributing. –  Sky Sanders Jul 10 '10 at 19:38
    
@code: I really need a sensible name for the function... any ideas? –  Nathan Osman Jul 10 '10 at 20:25
1  
makeanumberstackoverflowystyle –  Thomas McDonald Jul 10 '10 at 20:33
    
i am using formatNumber for lack of a better term. no need to be more explicit as the dev will be calling it as a member of your SO client library so context can be assumed. –  Sky Sanders Jul 10 '10 at 21:55
    
you're missing a few conversions. Numbers between 1000 and 9999 are formatted to look like 1,000, numbers between 10000 and 99999 are formatted to look like 10.4k, and finally what your method does is for numbers greater than 100000. –  Chase Florell Jul 15 '10 at 14:54
add comment

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .