Format numbers in JavaScript similar to C#

后端 未结 18 2111
傲寒
傲寒 2020-11-22 12:26

Is there a simple way to format numbers in JavaScript, similar to the formatting methods available in C# (or VB.NET) via ToString(\"format_provider\") or

相关标签:
18条回答
  • 2020-11-22 12:46

    Yes, there is definitely a way to format numbers properly in javascript, for example:

    var val=2489.8237
    
    val.toFixed(3) //returns 2489.824 (round up)
    val.toFixed(2) //returns 2489.82
    val.toFixed(7) //returns 2489.8237000 (padding)
    

    With the use of variablename.toFixed .

    And there is another function toPrecision() . For more detail you also can visit

    http://raovishal.blogspot.com/2012/01/number-format-in-javascript.html

    0 讨论(0)
  • 2020-11-22 12:46

    If you don't want to use jQuery, take a look at Numeral.js

    0 讨论(0)
  • 2020-11-22 12:48

    Here are some solutions, all pass the test suite, test suite and benchmark included, if you want copy and paste to test, try This Gist.

    Method 0 (RegExp)

    Base on https://stackoverflow.com/a/14428340/1877620, but fix if there is no decimal point.

    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.');
            a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,');
            return a.join('.');
        }
    }
    

    Method 1

    if (typeof Number.prototype.format1 === 'undefined') {
        Number.prototype.format1 = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.'),
                // skip the '-' sign
                head = Number(this < 0);
    
            // skip the digits that's before the first thousands separator 
            head += (a[0].length - head) % 3 || 3;
    
            a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&');
            return a.join('.');
        };
    }
    

    Method 2 (Split to Array)

    if (typeof Number.prototype.format2 === 'undefined') {
        Number.prototype.format2 = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('.');
    
            a[0] = a[0]
                .split('').reverse().join('')
                .replace(/\d{3}(?=\d)/g, '$&,')
                .split('').reverse().join('');
    
            return a.join('.');
        };
    }
    

    Method 3 (Loop)

    if (typeof Number.prototype.format3 === 'undefined') {
        Number.prototype.format3 = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }
    
            var a = this.toFixed(precision).split('');
            a.push('.');
    
            var i = a.indexOf('.') - 3;
            while (i > 0 && a[i-1] !== '-') {
                a.splice(i, 0, ',');
                i -= 3;
            }
    
            a.pop();
            return a.join('');
        };
    }
    

    Example

    console.log('======== Demo ========')
    var n = 0;
    for (var i=1; i<20; i++) {
        n = (n * 10) + (i % 10)/100;
        console.log(n.format(2), (-n).format(2));
    }
    

    Separator

    If we want custom thousands separator or decimal separator, use replace():

    123456.78.format(2).replace(',', ' ').replace('.', ' ');
    

    Test suite

    function assertEqual(a, b) {
        if (a !== b) {
            throw a + ' !== ' + b;
        }
    }
    
    function test(format_function) {
        console.log(format_function);
        assertEqual('NaN', format_function.call(NaN, 0))
        assertEqual('Infinity', format_function.call(Infinity, 0))
        assertEqual('-Infinity', format_function.call(-Infinity, 0))
    
        assertEqual('0', format_function.call(0, 0))
        assertEqual('0.00', format_function.call(0, 2))
        assertEqual('1', format_function.call(1, 0))
        assertEqual('-1', format_function.call(-1, 0))
        // decimal padding
        assertEqual('1.00', format_function.call(1, 2))
        assertEqual('-1.00', format_function.call(-1, 2))
        // decimal rounding
        assertEqual('0.12', format_function.call(0.123456, 2))
        assertEqual('0.1235', format_function.call(0.123456, 4))
        assertEqual('-0.12', format_function.call(-0.123456, 2))
        assertEqual('-0.1235', format_function.call(-0.123456, 4))
        // thousands separator
        assertEqual('1,234', format_function.call(1234.123456, 0))
        assertEqual('12,345', format_function.call(12345.123456, 0))
        assertEqual('123,456', format_function.call(123456.123456, 0))
        assertEqual('1,234,567', format_function.call(1234567.123456, 0))
        assertEqual('12,345,678', format_function.call(12345678.123456, 0))
        assertEqual('123,456,789', format_function.call(123456789.123456, 0))
        assertEqual('-1,234', format_function.call(-1234.123456, 0))
        assertEqual('-12,345', format_function.call(-12345.123456, 0))
        assertEqual('-123,456', format_function.call(-123456.123456, 0))
        assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
        assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
        assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
        // thousands separator and decimal
        assertEqual('1,234.12', format_function.call(1234.123456, 2))
        assertEqual('12,345.12', format_function.call(12345.123456, 2))
        assertEqual('123,456.12', format_function.call(123456.123456, 2))
        assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
        assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
        assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
        assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
        assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
        assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
        assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
        assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
        assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
    }
    
    console.log('======== Testing ========');
    test(Number.prototype.format);
    test(Number.prototype.format1);
    test(Number.prototype.format2);
    test(Number.prototype.format3);
    

    Benchmark

    function benchmark(f) {
        var start = new Date().getTime();
        f();
        return new Date().getTime() - start;
    }
    
    function benchmark_format(f) {
        console.log(f);
        time = benchmark(function () {
            for (var i = 0; i < 100000; i++) {
                f.call(123456789, 0);
                f.call(123456789, 2);
            }
        });
        console.log(time.format(0) + 'ms');
    }
    
    async = [];
    function next() {
        setTimeout(function () {
            f = async.shift();
            f && f();
            next();
        }, 10);
    }
    
    console.log('======== Benchmark ========');
    async.push(function () { benchmark_format(Number.prototype.format); });
    async.push(function () { benchmark_format(Number.prototype.format1); });
    async.push(function () { benchmark_format(Number.prototype.format2); });
    async.push(function () { benchmark_format(Number.prototype.format3); });
    next();
    
    0 讨论(0)
  • 2020-11-22 12:49

    http://code.google.com/p/javascript-number-formatter/ :

    • Short, fast, flexible yet standalone. Only 75 lines including MIT license info, blank lines & comments.
    • Accept standard number formatting like #,##0.00 or with negation -000.####.
    • Accept any country format like # ##0,00, #,###.##, #'###.## or any type of non-numbering symbol.
    • Accept any numbers of digit grouping. #,##,#0.000 or #,###0.## are all valid.
    • Accept any redundant/fool-proof formatting. ##,###,##.# or 0#,#00#.###0# are all OK.
    • Auto number rounding.
    • Simple interface, just supply mask & value like this: format( "0.0000", 3.141592)

    UPDATE

    As say Tomáš Zato here one line solution:

    (666.0).toLocaleString()
    numObj.toLocaleString([locales [, options]])
    

    which described in ECMA-262 5.1 Edition:

    • http://www.ecma-international.org/ecma-262/5.1/#sec-15.7.4.3
    • https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

    and will work in future versions of browsers...

    0 讨论(0)
  • 2020-11-22 12:53

    Here's another version:

    $.fn.digits = function () {
        return this.each(function () {
            var value = $(this).text();
            var decimal = "";
            if (value) {
                var pos = value.indexOf(".");
                if (pos >= 0) {
                    decimal = value.substring(pos);
                    value = value.substring(0, pos);
                }
                if (value) {
                    value = value.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
                    if (!String.isNullOrEmpty(decimal)) value = (value + decimal);
                    $(this).text(value);
                }
            }
            else {
                value = $(this).val()
                if (value) {
                    var pos = value.indexOf(".");
                    if (pos >= 0) {
                        decimal = value.substring(pos);
                        value = value.substring(0, pos);
                    }
                    if (value) {
                        value = value.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
                        if (!String.isNullOrEmpty(decimal)) value = (value + decimal);
                        $(this).val(value);
                    }
                }
            }
        })
    };
    
    0 讨论(0)
  • 2020-11-22 12:54

    Generally

    • Formatting numbers in JavaScript
    • Formatting numbers for currency display and more.

    In jQuery

    • autoNumeric (a decent number formatter & input helper with locale support for jQuery 1.5+)
    • jQuery Format (a clientSide implementation of Java's SimpleDateFormat and NumberFormat)
    • jquery-numberformatter (number formatter with locale support)
    0 讨论(0)
提交回复
热议问题