在js中作数字字符串补0

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

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


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

[javascript] view plain copy
  1. function pad(num, n) {  
  2.   return Array(n>num?(n-(''+num).length+1):0).join(0)+num;  
  3. }  

调用示例以下:
[javascript] view plain copy
  1. pad(100, 4);  // 输出:0100  

月影在这里分析了其中的技巧,以及代码长短与效率上的平衡:

http://hi.baidu.com/akira_cn/blog/item/90ba2a8b07c867dafc1f1045.html java

 

最后月影推荐的是“质朴长存法”: 算法

[javascript] view plain copy
  1. /* 质朴长存法  by lifesinger */  
  2. function pad(num, n) {  
  3.     var len = num.toString().length;  
  4.     while(len < n) {  
  5.         num = "0" + num;  
  6.         len++;  
  7.     }  
  8.     return num;  
  9. }  


这个在“没事就射鸟”同窗的博客里作了分析: 数组

http://lifesinger.org/blog/2009/08/the-harm-of-tricky-code/ 缓存

 

月影同窗有一件事是没有作的,就是没说明“为何那个短代码的效率更低?”。 闭包

答案是“表面看来,用array.join来替代循环是高效的,但忘掉了一个数组建立的开销”。对此有没有法子呢?我有过另外一个解决的思路。以下: app

[javascript] view plain copy
  1. /* 查表法(不完善)  by aimingoo */  
  2. pad = function(tbl) {  
  3.   return function(num, n) {  
  4.     return (((tbl[n = n-num.toString().length]) || (tbl[n] = Array(n).join(0))) + num);  
  5.   }  
  6. }([]);  


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

[javascript] view plain copy
  1. pad = function(tbl) {  
  2.   return function(num, n) {  
  3.     return (  
  4.       ((tbl[n = n-num.toString().length]) ||  
  5.        (tbl[n] = Array(n).join(0))) +  
  6.       num  
  7.     );  
  8.   }  
  9. }([]);  


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

 

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

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


固然,也能够象前面同样整理一下这个代码格式。或者,采用一个彻底不用“(函数式语言的)连续运算等技巧”的版本:

[javascript] view plain copy
  1. /* 查表法(过程式版本)  by aimingoo */  
  2. pad = function() {  
  3.   var tbl = [];  
  4.   return function(num, n) {  
  5.     var len = n-num.toString().length;  
  6.     if (len <= 0) return num;  
  7.     if (!tbl[len]) tbl[len] = (new Array(len+1)).join('0');  
  8.     return tbl[len] + num;  
  9.   }  
  10. }();  


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

相关文章
相关标签/搜索