zoukankan      html  css  js  c++  java
  • 在js中做数字字符串加0补位,效率分析

    分类: Jquery/YUI/ExtJs

    通常遇到的一个问题是日期的“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

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

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

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

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

    这个在“没事就射鸟”同学的博客里做了分析:

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

    月同学有一件事是没有做的,就是没说明“为什么那个短代码的效率更低?”。

    答案是“表面看来,用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是非常经常变化的,那么效率也不会有太大提升——对于过于频繁变化的系统,缓存就意义不大了。其实逻辑 都差不多,月影同学只是少走了一步而已。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aimingoo/archive/2009/08/28/4492592.aspx

  • 相关阅读:
    Python 学习笔记 11.模块(Module)
    Python 学习笔记 8.引用(Reference)
    Python 学习笔记 9.函数(Function)
    Python 学习笔记 6.List和Tuple
    Python 学习笔记 4.if 表达式
    Python 学习笔记 2.自省
    Python 学习笔记 3.简单类型
    Python 学习笔记 7.Dictionary
    Python 学习笔记 5.对象驻留
    Python 学习笔记 10.类(Class)
  • 原文地址:https://www.cnblogs.com/wangcq/p/3877716.html
Copyright © 2011-2022 走看看