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 相关文章推荐
JavaScript Base64编码和解码,实现URL参数传递。
Sep 18 Javascript
关于Blog顶部的滚动导航条代码
Sep 25 Javascript
js静态作用域的功能。
Dec 25 Javascript
浏览器兼容性问题大汇总
Dec 17 Javascript
JavaScript与jQuery实现的闪烁输入效果
Feb 18 Javascript
JS获取随机数和时间转换的简单实例
Jul 10 Javascript
分分钟玩转Vue.js组件(二)
Mar 01 Javascript
JS原生轮播图的简单实现(推荐)
Jul 22 Javascript
js防抖和节流的深入讲解
Dec 06 Javascript
Node.js使用supervisor进行开发中调试的方法
Mar 26 Javascript
浅谈react-router@4.0 使用方法和源码分析
Jun 04 Javascript
微信小程序学习之自定义滚动弹窗
Dec 20 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开发不能违背的安全规则 过滤用户输入
2011/05/01 PHP
[原创]PHPCMS遭遇会员投稿审核无效的解决方法
2017/01/11 PHP
Yii2 批量插入、更新数据实例
2017/03/15 PHP
layui框架实现文件上传及TP3.2.3(thinkPHP)对上传文件进行后台处理操作示例
2018/05/12 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
拖动table标题实现改变td的大小(css+js代码)
2013/04/16 Javascript
让元素在网页中可拖动示例代码
2013/08/13 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
2017/01/19 Javascript
jQuery实现选项卡功能(两种方法)
2017/03/08 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
AngularJS获取json数据的方法详解
2017/05/27 Javascript
jQuery实现键盘回车搜索功能
2017/07/25 jQuery
详解vue-cli 构建Vue项目遇到的坑
2017/08/30 Javascript
JavaScript中filter的用法实例分析
2019/02/27 Javascript
JavaScript undefined及null区别实例解析
2020/07/21 Javascript
python判断、获取一张图片主色调的2个实例
2014/04/10 Python
利用python爬取软考试题之ip自动代理
2017/03/28 Python
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
python实现定时自动备份文件到其他主机的实例代码
2018/02/23 Python
Python基于property实现类的特性操作示例
2018/06/15 Python
Python检查和同步本地时间(北京时间)的实现方法
2018/12/03 Python
Python深拷贝与浅拷贝用法实例分析
2019/05/05 Python
numpy:np.newaxis 实现将行向量转换成列向量
2019/11/30 Python
如何更改 pandas dataframe 中两列的位置
2019/12/27 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
希腊香水和化妆品购物网站:Parfimo.gr
2019/10/03 全球购物
乐高西班牙官方商店:LEGO Shop ES
2019/12/01 全球购物
编码实现字符串转整型的函数
2012/06/02 面试题
上海奥佳笔试题面试题
2016/11/16 面试题
请问软件开发中的设计模式你会使用哪些
2015/05/13 面试题
财务会计岗位职责
2015/02/03 职场文书
学校中秋节活动总结
2015/03/23 职场文书
Vue项目中如何封装axios(统一管理http请求)
2021/05/02 Vue.js
python缺失值的解决方法总结
2021/06/09 Python