代码之家  ›  专栏  ›  技术社区  ›  guitsaru

如何用前导零填充值?

  •  317
  • guitsaru  · 技术社区  · 7 年前

    在javascript中,推荐的零填充值的方法是什么?我想我可以构建一个自定义函数,将0填充到一个类型化的值上,但是我想知道是否有一种更直接的方法可以做到这一点?

    注: 我所说的“零填充”是指在数据库中的单词意义上(其中数字5的6位零填充表示为“000005”)。

    68 回复  |  直到 7 年前
        1
  •  184
  •   jsmorris    8 年前

    读者须知!

    正如评论家所指出的,这个解决方案是“聪明的”,并且 聪明的解决方案往往是,它的记忆力很强,而且相对来说 慢。如果您关心性能问题,请不要使用此解决方案!

    可能过时 :ECMAScript 2017包括 String.prototype.padStart Number.prototype.toLocaleString 从ECMAScript 3.1开始有吗?例子:

    var n=-0.1;
    n.toLocaleString('en', {minimumIntegerDigits:4,minimumFractionDigits:2,useGrouping:false})
    

    …将输出“-0000.10”。

    // or 
    const padded = (.1+"").padStart(6,"0");
    `-${padded}`
    

    …将输出“-0000.1”。

    你只需要一个简单的函数

    function zeroFill( number, width )
    {
      width -= number.toString().length;
      if ( width > 0 )
      {
        return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
      }
      return number + ""; // always return a string
    }
    

    如果要保留名称空间或其他内容,可以将其烘焙到库中。喜欢用 jQuery's extend .

        2
  •  288
  •   eych    7 年前

    简单的方法。您可以为pad添加字符串乘法并将其转换为函数。

    var pad = "000000";
    var n = '5';
    var result = (pad+n).slice(-pad.length);
    

    作为一个函数,

    function paddy(num, padlen, padchar) {
        var pad_char = typeof padchar !== 'undefined' ? padchar : '0';
        var pad = new Array(1 + padlen).join(pad_char);
        return (pad + num).slice(-pad.length);
    }
    var fu = paddy(14, 5); // 00014
    var bar = paddy(2, 4, '#'); // ###2
    
        3
  •  247
  •   Seaux    7 年前

    我不敢相信这里所有复杂的答案…只要用这个:

    var zerofilled = ('0000'+n).slice(-4);
    
        4
  •  105
  •   Nate    8 年前

    我最近真的不得不想出这样的办法。 我想必须有一种不用循环的方法。

    这就是我想到的。

    function zeroPad(num, numZeros) {
        var n = Math.abs(num);
        var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
        var zeroString = Math.pow(10,zeros).toString().substr(1);
        if( num < 0 ) {
            zeroString = '-' + zeroString;
        }
    
        return zeroString+n;
    }
    

    然后使用它提供一个数字到零的填充:

    > zeroPad(50,4);
    "0050"
    

    如果数字大于填充,则数字将超出填充范围:

    > zeroPad(51234, 3);
    "51234"
    

    小数也可以!

    > zeroPad(51.1234, 4);
    "0051.1234"
    

    如果您不介意污染全局命名空间,可以直接将其添加到数字:

    Number.prototype.leftZeroPad = function(numZeros) {
        var n = Math.abs(this);
        var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
        var zeroString = Math.pow(10,zeros).toString().substr(1);
        if( this < 0 ) {
            zeroString = '-' + zeroString;
        }
    
        return zeroString+n;
    }
    

    如果你想让小数占据填充空间:

    Number.prototype.leftZeroPad = function(numZeros) {
        var n = Math.abs(this);
        var zeros = Math.max(0, numZeros - n.toString().length );
        var zeroString = Math.pow(10,zeros).toString().substr(1);
        if( this < 0 ) {
            zeroString = '-' + zeroString;
        }
    
        return zeroString+n;
    }
    

    干杯!



    XDR 提出 对数变化 这似乎表现得更好。

    警告 :如果num等于零(例如zeropad(0,2)),则此函数失败。

    function zeroPad (num, numZeros) {
        var an = Math.abs (num);
        var digitCount = 1 + Math.floor (Math.log (an) / Math.LN10);
        if (digitCount >= numZeros) {
            return num;
        }
        var zeroString = Math.pow (10, numZeros - digitCount).toString ().substr (1);
        return num < 0 ? '-' + zeroString + an : zeroString + an;
    }
    

    说到表演, tomsmeding compared the top 3 answers ( 4 with the log variation )猜猜哪一个 少校 比其他两个强?:)

        5
  •  55
  •   chetbox    8 年前

    这是我用来填充最多7个字符的数字。

    ("0000000" + number).slice(-7)
    

    这种方法对大多数人来说可能已经足够了。

    编辑:如果要使其更通用,可以执行以下操作:

    ("0".repeat(padding) + number).slice(-padding)
    
        6
  •  24
  •   Objective Interested Person    10 年前

    不幸的是,对于这个问题有很多不必要的复杂建议,通常涉及编写自己的函数来进行数学或字符串操作,或者调用第三方实用程序。但是,在基本JavaScript库中,只有一行代码可以实现这一点。将这一行代码包装在函数中可能是值得的,这样可以避免指定您不希望更改的参数(如本地名称或样式)。

    var amount = 5;
    
    var text = amount.toLocaleString('en-US',
    {
        style: 'decimal',
        minimumIntegerDigits: 3,
        useGrouping: false
    });
    

    这将产生文本值“005”。您还可以使用数字的toLocaleString函数将0填充到小数点的右侧。

    var amount = 5;
    
    var text = amount.toLocaleString('en-US',
    {
        style: 'decimal',
        minimumFractionDigits: 2,
        useGrouping: false
    });
    

    这将产生文本值“5.00”。将usegrouping更改为true以对千使用逗号分隔符。

    注意使用 toLocaleString() 具有 locales options 争论 is standardized separately in ECMA-402 不在ecmascript中。到今天为止,有些浏览器 only implement basic support ,即 TolocalString()。 可以忽略任何参数。

    Complete Example

        7
  •  20
  •   jfriend00    12 年前

    如果预先知道填充数字不超过某个值,则有另一种方法可以在不使用循环的情况下执行此操作:

    var fillZeroes = "00000000000000000000";  // max number of zero fill ever asked for in global
    
    function zeroFill(number, width) {
        // make sure it's a string
        var input = number + "";  
        var prefix = "";
        if (input.charAt(0) === '-') {
            prefix = "-";
            input = input.slice(1);
            --width;
        }
        var fillAmt = Math.max(width - input.length, 0);
        return prefix + fillZeroes.slice(0, fillAmt) + input;
    }
    

    这里的测试用例: http://jsfiddle.net/jfriend00/N87mZ/

        8
  •  19
  •   Sterling Archer    9 年前

    建议(第3阶段)ES2017方法 .padStart() 您现在可以简单地做(在实现/支持时):

    string.padStart(maxLength, "0"); //max length is the max string length, not max # of fills
    
        9
  •  18
  •   Johann Philipp Strathausen    13 年前

    快速而肮脏的方式:

    y = (new Array(count + 1 - x.toString().length)).join('0') + x;
    

    对于x=5和count=6,您将得到y=“000005”

        10
  •  12
  •   Wilco    16 年前

    这是我为完成这项工作而设计的一个快速功能。如果有人有更简单的方法,请随意分享!

    function zerofill(number, length) {
        // Setup
        var result = number.toString();
        var pad = length - result.length;
    
        while(pad > 0) {
            result = '0' + result;
            pad--;
        }
    
        return result;
    }
    
        11
  •  11
  •   broofa    13 年前

    参加派对晚了,但我经常用这个结构做一些有价值的特别填充。 n ,已知为正,十进制:

    (offset + n + '').substr(1);
    

    在哪里? offset 是10 ^ ^数字。

    例如,填充到5位数,其中n=123:

    (1e5 + 123 + '').substr(1); // => 00123
    

    这个的十六进制版本稍微详细一点:

    (0x100000 + 0x123).toString(16).substr(1); // => 00123
    

    注1:我也喜欢@profitehloz的解决方案,它是这个的字符串版本,使用slice()的nifty负索引功能。

        12
  •  11
  •   Vitim.us    13 年前

    我真的不知道为什么,但没有人以最明显的方式做这件事。这里是我的实现。

    功能:

    /** Pad a number with 0 on the left */
    function zeroPad(number, digits) {
        var num = number+"";
        while(num.length < digits){
            num='0'+num;
        }
        return num;
    }
    

    原型:

    Number.prototype.zeroPad=function(digits){
        var num=this+"";
        while(num.length < digits){
            num='0'+num;
        }
        return(num);
    };
    

    非常简单,我看不出这是怎么简单的。出于某种原因,我在这里已经出现过很多次了,所以人们只是尽量避免以任何代价出现“for”和“while”循环。对于这样一个8位数的填充,使用regex可能会花费更多的周期。

        13
  •  9
  •   jasto salto    12 年前

    我用这个剪子得到一个5位数的表示

    (value+100000).toString().slice(-5) // "00123" with value=123
    
        14
  •  8
  •   tir    12 年前

    数学的力量!

    x=要填充的整数
    Y=要填充的零个数

    function zeroPad(x, y)
    {
       y = Math.max(y-1,0);
       var n = (x / Math.pow(10,y)).toFixed(y);
       return n.replace('.','');  
    }
    
        15
  •  8
  •   Herrbert    8 年前

    我没看到有人指出当你使用 String.prototype.substr() 如果是负数,则从右边开始计数。

    运算问题的一个线性解决方案,即数字5的6位零填充表示,是:

    console.log(("00000000" + 5).substr(-6));

    概括起来,我们会得到:

    function pad(num, len) { return ("00000000" + num).substr(-len) };
    
    console.log(pad(5, 6));
    console.log(pad(45, 6));
    console.log(pad(345, 6));
    console.log(pad(2345, 6));
    console.log(pad(12345, 6));
        16
  •  7
  •   kingjeffrey    12 年前

    第一个参数是任何实数,第二个参数是一个正整数,指定小数点左边的最小位数,第三个参数是一个可选的正整数,指定小数点右边的数字if。

    function zPad(n, l, r){
        return(a=String(n).match(/(^-?)(\d*)\.?(\d*)/))?a[1]+(Array(l).join(0)+a[2]).slice(-Math.max(l,a[2].length))+('undefined'!==typeof r?(0<r?'.':'')+(a[3]+Array(r+1).join(0)).slice(0,r):a[3]?'.'+a[3]:''):0
    }
    

    所以

               zPad(6, 2) === '06'
              zPad(-6, 2) === '-06'
           zPad(600.2, 2) === '600.2'
            zPad(-600, 2) === '-600'
             zPad(6.2, 3) === '006.2'
            zPad(-6.2, 3) === '-006.2'
          zPad(6.2, 3, 0) === '006'
            zPad(6, 2, 3) === '06.000'
        zPad(600.2, 2, 3) === '600.200'
    zPad(-600.1499, 2, 3) === '-600.149'
    
        17
  •  7
  •   Benny Bottema    11 年前

    不要重新发明轮子,使用 underscore string :

    jsFiddle

    var numToPad = '5';
    
    alert(_.str.pad(numToPad, 6, '0')); // yields: '000005'
    
        18
  •  7
  •   Lewis    10 年前

    这是ES6解决方案。

    function pad(num, len) {
      return '0'.repeat(len - num.toString().length) + num;
    }
    alert(pad(1234,6));
        19
  •  6
  •   Jack B    12 年前

    经过一段漫长的测试,在这个问题中找到了15种不同的功能/方法,我现在知道哪一种是最好的(最通用和最快的)。

    我从这个问题的答案中选择了15个函数/方法,并编写了一个脚本来测量执行100个PAD所花费的时间。每个垫子都会垫上数字 9 具有 2000 零点。这可能看起来太过分了,确实如此,但它为您提供了一个关于函数缩放的好主意。

    我使用的代码可以在这里找到: https://gist.github.com/NextToNothing/6325915

    您可以自己修改和测试代码。

    为了获得最通用的方法,必须使用循环。这是因为有大量的人可能会失败,而这将是成功的。

    那么,使用哪个循环呢?嗯,那将是一个 while 循环。A for 循环仍然很快,但是 虽然 循环只是稍微快一点(几毫秒),而且更干净。

    答案就像那些 Wilco , Aleksandar Toplek Vitim.us 会把工作做好的。

    就我个人而言,我尝试了一种不同的方法。我尝试使用递归函数填充字符串/数字。它的效果比加入数组的方法要好,但仍然不如for循环快。

    我的职能是:

    function pad(str, max, padder) {
      padder = typeof padder === "undefined" ? "0" : padder;
      return str.toString().length < max ? pad(padder.toString() + str, max, padder) : str;
    }
    

    您可以使用my函数来设置填充变量,也可以不设置填充变量。就像这样:

    pad(1, 3); // Returns '001'
    // - Or -
    pad(1, 3, "x"); // Returns 'xx1'
    

    就我个人而言,在测试之后,我会使用一个while循环的方法,比如 阿勒克山达托普莱克 ViTim.US . 但是,我会稍微修改它,以便您能够设置填充字符串。

    因此,我将使用以下代码:

    function padLeft(str, len, pad) {
        pad = typeof pad === "undefined" ? "0" : pad + "";
        str = str + "";
        while(str.length < len) {
            str = pad + str;
        }
        return str;
    }
    
    // Usage
    padLeft(1, 3); // Returns '001'
    // - Or -
    padLeft(1, 3, "x"); // Returns 'xx1'
    

    您也可以将其用作原型函数,方法是使用以下代码:

    Number.prototype.padLeft = function(len, pad) {
        pad = typeof pad === "undefined" ? "0" : pad + "";
        var str = this + "";
        while(str.length < len) {
            str = pad + str;
        }
        return str;
    }
    
    // Usage
    var num = 1;
    
    num.padLeft(3); // Returns '001'
    // - Or -
    num.padLeft(3, "x"); // Returns 'xx1'
    
        20
  •  6
  •   juFo    9 年前

    ECMAScript 2017年: 使用 PADSTART 帕德兰

    'abc'.padStart(10);         // "       abc"
    'abc'.padStart(10, "foo");  // "foofoofabc"
    'abc'.padStart(6,"123465"); // "123abc"
    

    更多信息:

        21
  •  5
  •   Lifehack    8 年前

    在所有现代浏览器中,您都可以使用

    numberStr.padStart(numberLength, "0");
    

    function zeroFill(num, numLength) {
      var numberStr = num.toString();
    
      return numberStr.padStart(numLength, "0");
    }
    
    var numbers = [0, 1, 12, 123, 1234, 12345];
    
    numbers.forEach(
      function(num) {
        var numString = num.toString();
        
        var paddedNum = zeroFill(numString, 5);
    
        console.log(paddedNum);
      }
    );

    这是MDN参考资料 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

        22
  •  4
  •   art    10 年前

    不是说这个问题需要更多的答案,但我想我会添加这个简单的罗达什版本。

    _.padLeft(number, 6, '0')

        23
  •  4
  •   MrE    10 年前

    最新的方法要简单得多:

    var number = 2
    number.toLocaleString(undefined, {minimumIntegerDigits:2})
    

    output: "02"

        24
  •  4
  •   ross chen    9 年前

    只是另一个解决方案,但我认为它更清晰。

    function zeroFill(text, size)
    {
      while (text.length < size){
      	text = "0" + text;
      }
      
      return text;
    }
        25
  •  3
  •   Jonathan Neal    16 年前

    这个不是本地的,但可能是最快的…

    zeroPad = function (num, count) {
        var pad = (num + '').length - count;
        while(--pad > -1) {
            num = '0' + num;
        }
        return num;
    };
    
        26
  •  3
  •   Aleksandar Toplek    13 年前

    我的解决方案

    Number.prototype.PadLeft = function (length, digit) {
        var str = '' + this;
        while (str.length < length) {
            str = (digit || '0') + str;
        }
        return str;
    };
    

    用法

    var a = 567.25;
    a.PadLeft(10); // 0000567.25
    
    var b = 567.25;
    b.PadLeft(20, '2'); // 22222222222222567.25
    
        27
  •  3
  •   lex82    9 年前

    为什么不使用递归?

    function padZero(s, n) {
        s = s.toString(); // in case someone passes a number
        return s.length >= n ? s : padZero('0' + s, n);
    }
    
        28
  •  2
  •   Rodrigo    16 年前

    一些MonkeyPatching也可以工作

    String.prototype.padLeft = function (n, c) {
      if (isNaN(n))
        return null;
      c = c || "0";
      return (new Array(n).join(c).substring(0, this.length-n)) + this; 
    };
    var paddedValue = "123".padLeft(6); // returns "000123"
    var otherPadded = "TEXT".padLeft(8, " "); // returns "    TEXT"
    
        29
  •  2
  •   Madbreaks    13 年前
    function pad(toPad, padChar, length){
        return (String(toPad).length < length)
            ? new Array(length - String(toPad).length + 1).join(padChar) + String(toPad)
            : toPad;
    }
    

    pad(5, 0, 6) = 000005

    pad('10', 0, 2) = 10 // don't pad if not necessary

    pad('S', 'O', 2) = SO

    ……等

    干杯

        30
  •  2
  •   d4nyll    11 年前

    这个 最简单的 最直接的解决方案。

    function zerofill(number,length) {
        var output = number.toString();
        while(output.length < length) {
          output = '0' + output;
        }
        return output;
    }