JS实现的4种数字千位符格式化方法分享


Posted in Javascript onMarch 02, 2015

所谓的数字千分位形式,即从个位数起,每三位之间加一个逗号。例如“10,000”。针对这个需求,我起初写了这样一个函数:

// 方法一

function toThousands(num) {

    var result = [ ], counter = 0;

    num = (num || 0).toString().split('');

    for (var i = num.length - 1; i >= 0; i--) {

        counter++;

        result.unshift(num[i]);

        if (!(counter % 3) && i != 0) { result.unshift(','); }

    }

    return result.join('');

}

方法一的执行过程就是把数字转换成字符串后,打散为数组,再从末尾开始,逐个把数组中的元素插入到新数组(result)的开头。每插入一个元素,counter就计一次数(加1),当counter为3的倍数时,就插入一个逗号,但是要注意开头(i为0时)不需要逗号。最后通过调用新数组的join方法得出结果。

方法一比较清晰易懂,也在项目中用了一段时间。但是直觉告诉我,它的性能并不好。

方法二——方法一的字符串版

// 方法二

function toThousands(num) {

    var result = '', counter = 0;

    num = (num || 0).toString();

    for (var i = num.length - 1; i >= 0; i--) {

        counter++;

        result = num.charAt(i) + result;

        if (!(counter % 3) && i != 0) { result = ',' + result; }

    }

    return result;

}

方法二是方法一的改良版,不把字符串打散为数组,始终对字符串操作。

方法三——循环匹配末尾的三个数字

// 方法三

function toThousands(num) {

    var num = (num || 0).toString(), re = /\d{3}$/, result = '';

    while ( re.test(num) ) {

        result = RegExp.lastMatch + result;

        if (num !== RegExp.lastMatch) {

            result = ',' + result;

            num = RegExp.leftContext;

        } else {

            num = '';

            break;

        }

    }

    if (num) { result = num + result; }

    return result;

}

方法三是完全不同的算法,通过正则表达式循环匹配末尾的三个数字,每匹配一次,就把逗号和匹配到的内容插入到结果字符串的开头,然后把匹配目标(num)赋值为还没匹配的内容(RegExp.leftContext)。此外,还要注意:

1.如果数字的位数是3的倍数时,最后一次匹配到的内容肯定是三个数字,但是最前面的三个数字前不需要加逗号;
2.如果数字的位数不是3的倍数,那num变量最后肯定会剩下1到2个数字,循环过后,要把剩余的数字插入到结果字符串的开头。

虽然方法三减少了循环次数(一次循环处理三个字符),但由于用到了正则表达式,一定程度上增加了消耗。

方法四——方法三的字符串版

// 方法四

function toThousands(num) {

    var num = (num || 0).toString(), result = '';

    while (num.length > 3) {

        result = ',' + num.slice(-3) + result;

        num = num.slice(0, num.length - 3);

    }

    if (num) { result = num + result; }

    return result;

}

事实上,截取末尾三个字符的功能可以通过字符串类型的slice、substr或substring方法做到。这样就可以避免使用正则表达式。

方法五——分组合并法

// 方法五

function toThousands(num) {

    var num = (num || 0).toString(), temp = num.length % 3;

    switch (temp) {

        case 1:

            num = '00' + num;

            break;

        case 2:

            num = '0' + num;

            break;

    }

    return num.match(/\d{3}/g).join(',').replace(/^0+/, '');

}

先把数字的位数补足为3的倍数,通过正则表达式,将其切割成每三个数字一个分组,再通过join方法添加逗号,最后还要把补的0移除。

方法六——懒人法

// 方法六

function toThousands(num) {

    return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');

}

​一直觉得这个格式化是可以通过一条正则表达式替换做出来的,但是需要用到断言等写法,无奈自己对这部分不太熟。Google了一下,还真找到了这么一条正则表达式,这估计是代码最短的实现。

测试结果

数字 执行5000次消耗的时间(ms)
方法一 方法二 方法三 方法四 方法五 方法六
1 4 1 3 1 14 2
10 14 1 3 0 7 2
100 12 1 2 4 5 3
1000 13 2 3 2 9 5
10000 21 4 3 1 6 3
100000 21 3 2 1 5 6

方法一和方法二的强烈对比表明,字符串操作的效率比数组操作的效率要高得多;方法六的测试结果告诉我们,代码长短跟性能高低没有关系。方法四的综合性能是最好的(但为何num为100的时候,性能有所降低呢,这个实在不解),主要原因是:

1.对比方法一、二,每次操作3个字符而不是1个字符,减少循环次数;
2.对比方法三、五、六,没有使用正则表达式,减少了消耗。

最后,我选择了方法四作为最终的优化方案。各位读者如有更好的实现方法或改良意见,可以发表评论。

Javascript 相关文章推荐
JS创建优美的页面滑动块效果 - Glider.js
Sep 27 Javascript
Javascript 八进制转义字符(8进制)
Apr 08 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
Mar 21 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
Sep 17 Javascript
基于JavaScript实现手机短信按钮倒计时(超简单)
Dec 30 Javascript
jquery实现简单的遮罩层
Jan 08 Javascript
JavaScript中的原型prototype完全解析
May 10 Javascript
Vue2实现组件props双向绑定
Dec 02 Javascript
javascript 中的继承实例详解
May 05 Javascript
vue.js给动态绑定的radio列表做批量编辑的方法
Feb 28 Javascript
Node.js中的cluster模块深入解读
Jun 11 Javascript
js实现通过开始结束控制的计时器
Feb 25 Javascript
js实现图片漂浮效果的方法
Mar 02 #Javascript
ECMAScript 5中的属性描述符详解
Mar 02 #Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
Mar 02 #Javascript
JavaScript数组常用方法
Mar 02 #Javascript
使用npm发布Node.JS程序包教程
Mar 02 #Javascript
js实现点击链接后窗口缩小并居中的方法
Mar 02 #Javascript
运行Node.js的IIS扩展iisnode安装配置笔记
Mar 02 #Javascript
You might like
PHP 获取远程文件大小的3种解决方法
2013/07/11 PHP
ThinkPHP简单使用memcache缓存的方法
2016/11/15 PHP
php readfile()修改文件上传大小设置
2017/08/11 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
文本加密解密
2006/06/23 Javascript
js实现上传图片之上传前预览图片
2013/03/25 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
使用 Node.js 实现图片的动态裁切及算法实例代码详解
2018/09/29 Javascript
JavaScript本地储存:localStorage、sessionStorage、cookie的使用
2020/10/13 Javascript
Python简单操作sqlite3的方法示例
2017/03/22 Python
django实现用户登陆功能详解
2017/12/11 Python
windows下Virtualenvwrapper安装教程
2017/12/13 Python
浅谈python数据类型及类型转换
2017/12/18 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
详解python持久化文件读写
2019/04/06 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
python django model联合主键的例子
2019/08/06 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
Python的in,is和id函数代码实例
2020/04/18 Python
python 实现全球IP归属地查询工具
2020/12/18 Python
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
玖熙女鞋美国官网:Nine West
2016/10/06 全球购物
为智能设备设计个性化保护套网站:caseable
2017/01/05 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
创业资金计划书
2014/02/06 职场文书
小学老师寄语大全
2014/04/04 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
2014个人年度工作总结
2014/12/15 职场文书
无罪辩护词范文
2015/05/21 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书
如何用Python搭建gRPC服务
2021/06/30 Python
html form表单基础入门案例讲解
2021/07/15 HTML / CSS