在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 相关文章推荐
个人总结的一些关于String、Function、Array的属性和用法
Jan 10 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
Jul 25 Javascript
微信小程序 http请求详细介绍
Oct 09 Javascript
原生js仿浏览器滚动条效果
Mar 02 Javascript
php 修改密码实现代码
May 24 Javascript
详解微信小程序中组件通讯
Oct 30 Javascript
vue数据初始化initState的实例详解
Apr 11 Javascript
layer弹出框确定前验证:弹出消息框的方法(弹出两个layer)
Sep 21 Javascript
解决VUE双向绑定失效的问题
Oct 29 Javascript
浅谈Three.js截图并下载的大坑
Nov 01 Javascript
vue-父子组件和ref实例详解
Nov 10 Javascript
vue 实现element-ui中的加载中状态
Nov 11 Javascript
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模块memcached使用指南
2014/12/08 PHP
php实现微信公众平台账号自定义菜单类
2015/10/11 PHP
详解WordPress开发中过滤属性以及Sql语句的函数使用
2015/12/25 PHP
LazyForm jQuery plugin 定制您的CheckBox Radio和Select
2009/10/24 Javascript
Jquery attr(&quot;checked&quot;) 返回checked或undefined 获取选中失效
2013/10/10 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
2014/01/23 Javascript
nodejs简单实现中英文翻译
2015/05/04 NodeJs
jQuery+ajax实现无刷新级联菜单示例
2015/05/21 Javascript
详解javascript获取url信息的常见方法
2016/12/19 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
新闻上下滚动jquery 超简洁(必看篇)
2017/01/21 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
2018/03/02 Javascript
详解JSON Web Token 入门教程
2018/07/30 Javascript
echarts大屏字体自适应的方法步骤
2019/07/12 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
微信小程序激励式视频广告组件使用详解
2019/12/06 Javascript
Vue v-bind动态绑定class实例方法
2020/01/15 Javascript
JavaScript 获取滚动条位置并将页面滑动到锚点
2021/02/08 Javascript
[01:10]DOTA2次级职业联赛 - EP战队宣传片
2014/12/01 DOTA
[04:12]第二届DOTA2亚洲邀请赛选手传记-Newbee.Sccc
2017/04/03 DOTA
python中map()与zip()操作方法
2016/02/27 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
flask入门之表单的实现
2018/07/18 Python
python使用thrift教程的方法示例
2019/03/21 Python
python数据持久存储 pickle模块的基本使用方法解析
2019/08/30 Python
利用Python实现朋友圈中的九宫格图片效果
2020/09/03 Python
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
Kickers鞋英国官网:男士、女士和儿童鞋
2021/03/08 全球购物
考博自荐信
2013/10/25 职场文书
学生周末回家住宿长期请假条
2014/02/15 职场文书
革命先烈的英雄事迹材料
2014/02/15 职场文书
《草船借箭》教学反思
2016/02/23 职场文书
python字符串的一些常见实用操作
2022/04/06 Python
USB TYPE-C 或将成为所有智能手机充电标准
2022/04/21 数码科技
CSS 实现磨砂玻璃(毛玻璃)效果样式
2023/05/21 HTML / CSS