在js中做数字字符串补0(js补零)


Posted in Javascript onMarch 25, 2017

通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的比较简单的处理方法是这样:

function formatDate(d) {
 var D=['00','01','02','03','04','05','06','07','08','09']
 with (d || new Date) return [
  [getFullYear(), D[getMonth()+1]||getMonth()+1, D[getDate()]||getDate()].join('-'),
  [D[getHours()]||getHours(), D[getMinutes()]||getMinutes(), D[getSeconds()]||getSeconds()].join(':')
 ].join(' ');
}

这种方法是逻辑比较简单的,而且规则也简单。除了with(d||new Date)的使用之外,也算不上什么技巧。但是,如果用这种方法来做数字字符串补0,那么结果显然不妙。51js的月影提供了另一个方案:

function pad(num, n) {
 return Array(n>num?(n-(''+num).length+1):0).join(0)+num;
}

调用示例如下:

pad(100, 4); // 输出:0100

月影在这里分析了其中的技巧,以及代码长短与效率上的平衡:
最后月影推荐的是“质朴长存法”:

/* 质朴长存法 by lifesinger */
function pad(num, n) {
  var len = num.toString().length;
  while(len < n) {
    num = "0" + num;
    len++;
  }
  return num;
}

这个在“没事就射鸟”同学的博客里做了分析
月影同学有一件事是没有做的,就是没说明“为什么那个短代码的效率更低?”。
答案是“表面看来,用array.join来替代循环是高效的,但忘掉了一个数组创建的开销”。对此有没有法子呢?我有过另一个解决的思路。如下:

/* 查表法(不完善) by aimingoo */
pad = function(tbl) {
 return function(num, n) {
  return (((tbl[n = n-num.toString().length]) || (tbl[n] = Array(n).join(0))) + num);
 }
}([]);

这个路子跟前面的formatDate()是一样的,只不是formatDate()里的表是一个确定的数组,而这里的数组则是动态生成,然后缓存在tbl[]里面。这个缓存的tbl[]数组是使用一个函数调用参数的形式,保持在最终的pad()函数的上层闭包里面。为了让上面的这个过程清晰一点,我重排代码格式如下:

pad = function(tbl) {
 return function(num, n) {
  return (
   ((tbl[n = n-num.toString().length]) ||
    (tbl[n] = Array(n).join(0))) +
   num
  );
 }
}([]);

好的。到这里,先别急,还有两个问题要解决。其一,当不需要补0时,上述的tbl[0]返回空值,所以会进入到“||”运算的第二个分支,因此导致Array()重算一次,也就是说“不补0的情况效率其实最低”。其二,当num长度大于n时,也就变成了“补负数个零”。“补负数个零”显然不行,一般对此处理成“不需要补零”,于是又回到了第一个问题。

这两个问题可以一次解决,其实就是多一次判断:

/* 查表法(完善版本) by aimingoo */
pad = function(tbl) {
 return function(num, n) {
  return (0 >= (n = n-num.toString().length)) ? num : (tbl[n] || (tbl[n] = Array(n+1).join(0))) + num;
 }
}([]);

当然,也可以象前面一样整理一下这个代码格式。或者,采用一个完全不用“(函数式语言的)连续运算等技巧”的版本:

/* 查表法(过程式版本) by aimingoo */
pad = function() {
 var tbl = [];
 return function(num, n) {
  var len = n-num.toString().length;
  if (len <= 0) return num;
  if (!tbl[len]) tbl[len] = (new Array(len+1)).join('0');
  return tbl[len] + num;
 }
}();

算法永远都是如此,要不是时间换空间,要不就是空间换时间。射雕同学的“质朴长存法”是时间换空间的方法,而这里的查表法则是空间换时间的方案。这个函数会在tbl中持续一个字符串数组,如果num是非常经常变化的,那么效率也不会有太大提升——对于过于频繁变化的系统,缓存就意义不大了。其实逻辑都差不多,月影同学只是少走了一步而已。

Javascript 相关文章推荐
编写Js代码要注意的几条规则
Sep 10 Javascript
手把手教你自己写一个js表单验证框架的方法
Sep 14 Javascript
获取鼠标在div中的相对位置的实现代码
Dec 30 Javascript
js自定义鼠标右键的实现原理及源码
Jun 23 Javascript
Javascript中的数据类型之旅
Oct 18 Javascript
浅谈js中对象的使用
Aug 11 Javascript
Bootstrap栅格系统学习笔记
Nov 25 Javascript
手写简单的jQuery雪花飘落效果实例
Apr 22 jQuery
小程序点赞收藏功能的实现代码示例
Sep 07 Javascript
layui动态表头的实现代码
Aug 22 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 Javascript
vue 动态添加的路由页面刷新时失效的原因及解决方案
Feb 26 Vue.js
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
Mar 25 #Javascript
JS去掉字符串前后空格或去掉所有空格的用法
Mar 25 #Javascript
javascript作用域链与执行环境详解
Mar 25 #Javascript
vue中用动态组件实现选项卡切换效果
Mar 25 #Javascript
使用vue.js写一个tab选项卡效果
Mar 25 #Javascript
JavaScript 实现 Tab 点击切换实例代码
Mar 25 #Javascript
JS操作xml对象转换为Json对象示例
Mar 25 #Javascript
You might like
PHP+javascript液晶时钟
2006/10/09 PHP
图文介绍PHP添加Redis模块及连接
2015/07/28 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
PHP数组遍历的几种常见方式总结
2019/02/15 PHP
简单JS代码压缩器
2006/10/12 Javascript
随机显示经典句子或诗歌的javascript脚本
2007/08/04 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
2013/01/23 Javascript
在父页面调用子页面的JS方法
2013/09/29 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
js获取当前时间(昨天、今天、明天)
2016/11/23 Javascript
jQuery Validation Engine验证控件调用外部函数验证的方法
2017/01/18 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
Vue 去除路径中的#号
2018/04/19 Javascript
使用Vue如何写一个双向数据绑定(面试常见)
2018/04/20 Javascript
Vue2.0生命周期的理解
2018/08/20 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
ant design实现圈选功能
2019/12/17 Javascript
jquery绑定事件 bind和on的用法与区别分析
2020/05/22 jQuery
[55:02]2014 DOTA2国际邀请赛中国区预选赛 HGT VS Orenda
2014/05/21 DOTA
python检测远程端口是否打开的方法
2015/03/14 Python
Cpy和Python的效率对比
2015/03/20 Python
解读Python编程中的命名空间与作用域
2015/10/16 Python
python类中super()和__init__()的区别
2016/10/18 Python
python下如何查询CS反恐精英的服务器信息
2017/01/17 Python
Python中struct模块对字节流/二进制流的操作教程
2017/01/21 Python
Python实现 多进程导入CSV数据到 MySQL
2017/02/26 Python
Python调用服务接口的实例
2019/01/03 Python
预订从美国飞往印度的机票:MyTicketsToIndia
2017/05/19 全球购物
Lulu & Georgia官方网站:购买地毯、家具、抱枕、壁纸、床上用品等
2018/03/19 全球购物
电信营业员自我评价分享
2014/01/17 职场文书
机关驾驶员违规检讨书
2014/09/13 职场文书
员工旷工检讨书
2015/08/15 职场文书
pandas DataFrame.shift()函数的具体使用
2021/05/24 Python
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers