如何用前导零填充值?

Wil*_*lco 354 javascript zerofill

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

注意: "zerofilled"是指数据库中的单词意义(数字5的6位零填充表示为"000005").

pro*_*olz 306

简单的方法.您可以为打击垫添加字符串乘法并将其转换为函数.

var pad = "000000";
var n = '5';
var result = (pad+n).slice(-pad.length);
Run Code Online (Sandbox Code Playgroud)

作为一个功能,

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
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的解决方案,我见过最好的解决方案.为清楚起见,这是一个更简单的版本我用来填充时间格式的分钟:('0'+分钟).slice(-2) (90认同)
  • 这有一个**致命的FLAW**,大于预期的数字 - 这是一个非常常见的事件.例如,`paddy(888,2)`根据需要产生`88`而不是'888`.这个答案也没有处理负数. (41认同)
  • 这比使用while循环的实现慢5倍:https://gist.github.com/4382935 (15认同)
  • @BrockAdams,zerofill通常用于固定宽度的数字/格式化情况 - 因此,如果在尝试进行2位数的zerofill时给出3位数字,我认为它实际上不太可能(甚至不是问题). (8认同)
  • ("000000" + somenum).substr(-6,6) 其中零的数量和 -6,6 对应于焊盘宽度。同样的想法,但 slice 少了一个参数;不确定切片是比 subtr 快还是慢。当然,我的解决方案不需要变量赋值。 (2认同)

Sea*_*aux 282

我无法相信这里所有复杂的答案......只需使用:

var zerofilled = ('0000'+n).slice(-4);
Run Code Online (Sandbox Code Playgroud)

  • 好的除了负数和超过4位的数字. (24认同)
  • @wberry这不是生产就绪代码,而是解决手头问题的基础知识的简单解释.Aka很容易确定一个数字是正数还是负数,并在需要时添加适当的符号,所以我不想用这个简单的例子.此外,使用数字长度作为arg并使用它来代替我的硬编码值也很容易. (9认同)
  • 我喜欢这个答案.在我自己的特定情况下,我知道数字总是正数而且不超过3位数,当你用前导0填充并且你的输入是众所周知的时候通常就是这种情况.太好了! (5认同)
  • @Seaux,您说:_“无法相信所有复杂的答案” _,然后在评论时开始向自己解释复杂性。这意味着您了解从某些角度看您的答案并不完美。因此很复杂。 (4认同)
  • @OmShankar通过"复杂的答案",我没有提到解释或详细的答案(尽管我的答案不是,这显然在这个网站上受到鼓励),而是包含不必要的代码复杂性的答案. (2认同)
  • `('000'+n).切片(-4)` (2认同)
  • @Seaux,您提供的答案太简单而无法正确,从而破坏了您关于不必要的复杂性的观点。 (2认同)

Pet*_*ley 204

读者注意!

正如评论者所指出的那样,这种解决方案是"聪明的",而且通常是巧妙的解决方案,它的内存密集且相对较慢.如果性能是您的关注点,请不要使用此解决方案!

可能过时:ECMAScript 2017包括 String.prototype.padStart Number.prototype.toLocaleString自ECMAScript 3.1以来就存在.例:

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

...将输出"-0000.10".

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

...将输出"-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
}
Run Code Online (Sandbox Code Playgroud)

如果你想保存命名空间或其他什么,你可以将它烘焙到一个库中.就像jQuery的扩展一样.

  • 从ECMAScript 2017开始,有一个内置函数[padStart](https://leanpub.com/exploring-es2016-es2017/read#ch_string-padding). (9认同)
  • 这对负值不起作用:zeroFill(-10,7) - >"0000-10" (6认同)
  • 每次要填充值时都不是创建新数组的粉丝.如果他们在做大型#这些的(例如,是在做每秒这些操作的1000年使Node.js服务器上的读者应该知道的潜在的内存和GC的影响.@ profitehlolz的答案似乎是更好的解决方案.) (5认同)
  • 这里有三个最佳答案的绩效衡量标准:http://jsperf.com/left-zero-pad (2认同)

cod*_*joe 107

我最近不得不想出这样的东西.我认为必须有一种方法可以不使用循环.

这就是我提出的.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

> zeroPad(50,4);
"0050"
Run Code Online (Sandbox Code Playgroud)

如果数字大于填充,则数字将扩展到填充之外:

> zeroPad(51234, 3);
"51234"
Run Code Online (Sandbox Code Playgroud)

小数也很好!

> zeroPad(51.1234, 4);
"0051.1234"
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢小数,请在填充中占用空间:

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;
}
Run Code Online (Sandbox Code Playgroud)

干杯!



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;
}
Run Code Online (Sandbox Code Playgroud)

说到性能,tomsmeding 比较了前三个答案(4个与日志变化).猜猜哪一个主要优于其他两个?:)

  • +1.与较高的投票答案不同,这个处理负数并且在溢出时不会返回严重错误!!?! (13认同)
  • 这里有三个最佳答案的绩效衡量标准:http://jsperf.com/left-zero-pad (10认同)
  • 这很好,我喜欢它的可读性和健壮性.我唯一要改变的是`numZeros`参数的名称,因为它具有误导性.它不是您要添加的零的数量,而是数字应该是的最小长度.一个更好的名字是`numLength`甚至是`length`. (9认同)
  • 通过使用对数,我将这个答案的性能提高了100%以上.请参阅[http://jsperf.com/left-zero-pad/10](http://jsperf.com/left-zero-pad/10)中的对数测试用例 (4认同)
  • 原始解决方案更好,如果`num`可以为零,则对数变化不起作用... (2认同)

che*_*box 65

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

("0000000" + number).slice(-7)
Run Code Online (Sandbox Code Playgroud)

这种方法可能足以满足大多数人的需求.

编辑:如果您想使它更通用,您可以这样做:

("0".repeat(padding) + number).slice(-padding)
Run Code Online (Sandbox Code Playgroud)

  • 道歉,我应该提到这对负数不起作用.不过,我认为这涉及更常见的正数案例.它至少可以满足我的需求! (4认同)
  • `(new Array(padding + 1).join("0")`可以替换为`"0".repeat(padding)` (3认同)
  • 很好的解决方案“padStart()” (3认同)

Dan*_*ace 27

不幸的是,对于这个问题有很多不必要的复杂建议,通常涉及编写自己的函数来进行数学或字符串操作或调用第三方实用程序.但是,只需一行代码就可以在基本JavaScript库中执行此操作的标准方法.在函数中包含这一行代码可能是值得的,以避免必须指定您永远不想更改的参数,如本地名称或样式.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumIntegerDigits: 3,
    useGrouping: false
});
Run Code Online (Sandbox Code Playgroud)

这将为文本生成"005"的值.您还可以使用Number的toLocaleString函数将零填充到小数点的右侧.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumFractionDigits: 2,
    useGrouping: false
});
Run Code Online (Sandbox Code Playgroud)

这将为文本生成"5.00"的值.将useGrouping更改为true以使用逗号分隔符数千.

请注意,使用toLocaleString()with localesoptionsarguments 在ECMA-402中单独标准化,而不是在ECMAScript中标准化.截至今天,一些浏览器只实现基本支持,即toLocaleString()可以忽略任何参数.

完整的例子

  • 确实,许多内置 JavaScript 函数在循环处理大量数据时表现不佳,但我认为您不应该为此使用 JavaScript,即使是像 Node.js 这样的服务器端。如果您有大量数据需要在服务器端处理,则应该使用更好的平台,例如 .NET 或 Java。如果您正在处理客户端数据以显示给最终用户,则应该仅处理当前呈现到最终用户屏幕的数据。例如,仅渲染表的可见行,而不处理其他道路的数据。 (2认同)

Ste*_*her 22

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

string.padStart(maxLength, "0"); //max length is the max string length, not max # of fills
Run Code Online (Sandbox Code Playgroud)


jfr*_*d00 21

如果预先知道填充数不超过某个值,那么还有另一种方法可以做到这一点,没有循环:

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;
}
Run Code Online (Sandbox Code Playgroud)

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


Joh*_*sen 19

快速而肮脏的方式:

y = (new Array(count + 1 - x.toString().length)).join('0') + x;
Run Code Online (Sandbox Code Playgroud)

对于x = 5和count = 6,你将得到y ="000005"

  • @OrrSiloni:最短的代码解决方案实际上是`('0000'+ n).slice(-4)` (3认同)

Wil*_*lco 14

这是我想出来完成这项工作的快速功能.如果有人有更简单的方法,请随时分享!

function zerofill(number, length) {
    // Setup
    var result = number.toString();
    var pad = length - result.length;

    while(pad > 0) {
        result = '0' + result;
        pad--;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)


bro*_*ofa 12

迟到这里的派对,但我经常使用这个构造来做一些值的ad-hoc填充n,已知是一个正数,十进制:

(offset + n + '').substr(1);
Run Code Online (Sandbox Code Playgroud)

offset10 ^^位数在哪里.

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

(1e5 + 123 + '').substr(1); // => 00123
Run Code Online (Sandbox Code Playgroud)

这个的十六进制版本稍微冗长一点:

(0x100000 + 0x123).toString(16).substr(1); // => 00123
Run Code Online (Sandbox Code Playgroud)

注1:我也喜欢@ profitehlolz的解决方案,这是使用slice()的漂亮的负索引功能的字符串版本.


Vit*_*.us 12

我真的不知道为什么,但没有人以最明显的方式做到这一点.这是我的实施.

功能:

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

原型:

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

非常简单,我无法看到任何方式如何更简单.出于某种原因,我似乎很多次在这里,人们只是试图不惜任何代价避免'for'和'while'循环.使用正则表达式可能会花费更多周期来进行这种简单的8位填充.


小智 11

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

(value+100000).toString().slice(-5) // "00123" with value=123
Run Code Online (Sandbox Code Playgroud)


小智 9

数学的力量!

x =填充
y的整数y = 填充的零的数量

function zeroPad(x, y)
{
   y = Math.max(y-1,0);
   var n = (x / Math.pow(10,y)).toFixed(y);
   return n.replace('.','');  
}
Run Code Online (Sandbox Code Playgroud)


juF*_*uFo 9

ECMAScript 2017:使用padStartpadEnd

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
Run Code Online (Sandbox Code Playgroud)

更多信息:


Ste*_*uan 9

我没有看到有人指出这样一个事实:当你使用带有负数的String.prototype.substr()时,它从右边算起.

OP问题的单线解决方案是5号的6位零填充表示:

console.log(("00000000" + 5).substr(-6));
Run Code Online (Sandbox Code Playgroud)

概括我们会得到:

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));
Run Code Online (Sandbox Code Playgroud)


Jac*_*lan 8

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

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
}
Run Code Online (Sandbox Code Playgroud)

所以

           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'
Run Code Online (Sandbox Code Playgroud)


Ben*_*ema 8

不要重新发明轮子,使用下划线字符串:

的jsfiddle

var numToPad = '5';

alert(_.str.pad(numToPad, 6, '0')); // yields: '000005'
Run Code Online (Sandbox Code Playgroud)


Lew*_*wis 8

这是ES6解决方案.

function pad(num, len) {
  return '0'.repeat(len - num.toString().length) + num;
}
alert(pad(1234,6));
Run Code Online (Sandbox Code Playgroud)


Jac*_*k B 7

经过长时间的长时间测试,在这个问题答案中找到了15个不同的功能/方法,我现在知道哪个是最好的(最通用和最快).

我从这个问题的答案中选取了15个函数/方法,并制作了一个脚本来测量执行100个填充所需的时间.每个打击垫都会92000零填充数字.这可能看起来过分,而且它可以让您对功能的扩展有一个很好的了解.

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

随意修改和测试代码.

为了获得最通用的方法,您必须使用循环.这是因为非常多的人可能会失败,而这将成功.

那么,使用哪个循环?好吧,这将是一个while循环.一for环依然很快,但while环只是稍快(几毫秒) -和清洁.

答案就像那些Wilco,Aleksandar ToplekVitim.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;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用或不使用我的函数来设置填充变量.像这样:

pad(1, 3); // Returns '001'
// - Or -
pad(1, 3, "x"); // Returns 'xx1'
Run Code Online (Sandbox Code Playgroud)

就个人而言,在我的测试之后,我会使用带有while循环的方法,比如Aleksandar ToplekVitim.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'
Run Code Online (Sandbox Code Playgroud)

您也可以使用此代码将其用作原型函数:

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'
Run Code Online (Sandbox Code Playgroud)


Lif*_*ack 7

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

numberStr.padStart(numberLength, "0");
Run Code Online (Sandbox Code Playgroud)

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);
  }
);
Run Code Online (Sandbox Code Playgroud)

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


Art*_*Art 5

并不是说这个问题需要更多答案,但是我想我应该添加一个简单的lodash版本。

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

  • 有些人可能会抗议“我不想使用lodash”,但这已经不再是有效的参数了,因为您只能安装以下功能:`npm install --save lodash.padleft`,然后`从lodash.padleft导入padLeft并省略_。 (3认同)
  • 更好:`var zfill = _.partialRight(_.padStart, '0');` (2认同)

MrE*_*MrE 5

执行此操作的最新方法要简单得多:

var number = 2
number.toLocaleString(undefined, {minimumIntegerDigits:2})
Run Code Online (Sandbox Code Playgroud)

output: "02"


Art*_*hur 5

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

function zeroFill(text, size)
{
  while (text.length < size){
  	text = "0" + text;
  }
  
  return text;
}
Run Code Online (Sandbox Code Playgroud)