在JavaScript中用前导零填充数字[重复]

Posted

技术标签:

【中文标题】在JavaScript中用前导零填充数字[重复]【英文标题】:Pad a number with leading zeros in JavaScript [duplicate] 【发布时间】:2012-04-21 20:31:13 【问题描述】:

javascript 中,我需要有填充。

例如,如果我有数字 9,它将是“0009”。如果我有一个数字,比如 10,它将是“0010”。注意它总是包含四位数字。

这样做的一种方法是将数字减去 4 以获得我需要输入的 0 的数量。

有没有更巧妙的方法来做到这一点?

【问题讨论】:

("0000" + num).substr(-4,4); //又短又甜 ("0000" + num).slice(-4) 将在任何地方工作,AFAIK 如果你已经在使用 lodash:lodash.com/docs#padLeft ('000' + num).slice(-4) 就够了;) ES2017:String(n).padStart(4, '0') 【参考方案1】:

ES2017 更新

您可以使用内置的String.prototype.padStart()

n = 9;
String(n).padStart(4, '0'); // '0009'

n = 10;
String(n).padStart(4, '0'); // '0010'

到目前为止,还没有很多“花哨”:

function pad(n, width, z) 
  z = z || '0';
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;

当您使用数字初始化数组时,它会创建一个数组,并将 length 设置为该值,以便该数组看起来包含那么多 undefined 元素。尽管一些 Array 实例方法跳过了没有值的数组元素,.join() 没有,或者至少不完全;它将它们视为它们的值是空字符串。因此,您会在每个数组元素之间获得零字符(或任何“z”)的副本;这就是为什么里面有一个+ 1

示例用法:

pad(10, 4);      // 0010
pad(9, 4);       // 0009
pad(123, 4);     // 0123

pad(10, 4, '-'); // --10

【讨论】:

“当你用数字初始化一个数组时,它会创建一个包含那么多未定义元素的数组。” - 我认为这是不正确的。它只是设置length 属性并加入迭代length 次。未定义属性的访问总是返回undefined。请参阅 "5" in Array(5)"0" in [1] @Pointy 分配空间是程序员不可见的实现细节(没有开放的实现,我知道这样做(Rhino,V8,SM,JSC)任何分配内存的实现and 暴露属性违反了非常清楚的 EcmaScript 规范(在“数组构造函数 15.4.2.2”下)。这没什么大不了的,否则答案很好,它会是如果你修复了这个细节很好。 感谢您的回答,但是像“n”和“z”这样的变量对于它们在做什么并不直观。 你真的需要一个数组吗? function pad(n, width, z) while(n.length<width) n = '' + z + n; return n; “光滑”,紧凑且可扩展。 function pad(n, width=3, z=0) return (String(z).repeat(width) + String(n)).slice(String(n).length)【参考方案2】:
function padToFour(number) 
  if (number<=9999)  number = ("000"+number).slice(-4); 
  return number;

类似的东西?

额外的难以理解但更流畅的单行 ES6 版本:

let padToFour = number => number <= 9999 ? `000$number`.slice(-4) : number;

ES6 主义:

let 是块作用域变量(与 var 的函数作用域相反) =&gt; 是一个箭头函数,除其他外替换 function 并由其参数前置 如果箭头函数采用单个参数,您可以省略括号(因此number =&gt;) 如果箭头函数体有一行以return 开头,您可以省略大括号和return 关键字,而只需使用表达式 为了将函数体缩减为一行,我作弊并使用了三元表达式

【讨论】:

简单但没那么新颖;我最近不得不做类似的事情,并在网上找到了这种方法。 只投了票,因为这不是模块化方法(仅适用于 4 位数字)。当然,这是对特定问题的特定答案,但包含长度选项会更好(与其他答案一样)。 我喜欢 slice 的用法。但是,正如@doubleJ 提到的,请注意,这种方法的一个限制是将数字截断为最后 4 位。 实际上@JorgeOrpinel 它不会被截断。 if 语句导致切片操作仅对四位或更少位数的数字进行操作。五位数字的值至少为 10000,而不是 我认为自 sprintf (padToFour, "%04d", number); 时代以来我们已经取得了倒退【参考方案3】:

试试:

String.prototype.lpad = function(padString, length) 
    var str = this;
    while (str.length < length)
        str = padString + str;
    return str;

现在测试:

var str = "5";
alert(str.lpad("0", 4)); //result "0005"
var str = "10"; // note this is string type
alert(str.lpad("0", 4)); //result "0010"

DEMO


ECMAScript 2017 中,我们有新方法 padStartpadEnd 具有以下语法。

"string".padStart(targetLength [,padString]):

所以现在我们可以使用

const str = "5";
str.padStart(4, "0"); // "0005"

【讨论】:

为了完整起见,您应该从最后一个字符串中取出最后一个length 字符,以处理padString 是多个符号的情况。 按照您的操作方式,"5".lpad("--", 4) 将生成“----5”而不是“---5”。 不建议将字符串原型扩展为任何其他内置。 +1 用于指出 ES8 解决方案。这里描述了一个简单的 polyfill:2ality.com/2015/11/string-padding.html ES8 解决方案应该是当今这个问题的答案。你应该把它放在答案的顶部。【参考方案4】:

有趣的是,我最近不得不这样做。

function padDigits(number, digits) 
    return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;

像这样使用:

padDigits(9, 4);  // "0009"
padDigits(10, 4); // "0010"
padDigits(15000, 4); // "15000"

不漂亮,但有效。

【讨论】:

@doubleJ Pointy's 和我的实际上非常相似,如果不完全相同的话,除了他的具有能够填充除 0 以外的东西的功能。你可以使用他的类似 pad(15, 3) 一样的东西我的使用方式。 我wrote a similar answer,我首先将num转为str并使用return (Array(Math.max(5-str.length, 0)).join("0") + str);,只是为了防止另一个Q被删除 要处理负数,请使用数字的绝对值,然后在最终结果上加上一个负号 ('-')。 (number &lt; 0 ? '-' : '') + Array(Math.max(digits - String(value).length + 1, 0)).join(0) + value 其中“价值”是Math.abs(number) 我非常喜欢这个解决方案@NeilMonroe,但你愿意为我们分解一下吗?作为评论,它不是很可读。 :)【参考方案5】:

你确实说过你有一个号码-

String.prototype.padZero= function(len, c)
    var s= '', c= c || '0', len= (len || 2)-this.length;
    while(s.length<len) s+= c;
    return s+this;

Number.prototype.padZero= function(len, c)
    return String(this).padZero(len,c);

【讨论】:

很想知道为什么这没有得到投票。似乎是最合乎逻辑和最完整的解决方案。示例用法 var v=2; v.padZero(4); v.padZero(4,'+');产生'0002''+++2' 我一直在寻找用前导零填充,这是我选择的解决方案。应该得到更多的支持。 因为这个解决方案太具体了... ``` String.prototype.lpad = function(len, c) var s= '', c= c || ' ', len= (len || 2)-this.length;而(s.length 也刚刚意识到四个空格的markdown在这些评论字段中不起作用【参考方案6】:

你可以这样做:

function pad ( num, size ) 
  return ( Math.pow( 10, size ) + ~~num ).toString().substring( 1 );

编辑:这只是一个函数的基本想法,但要添加对更大数字(以及无效输入)的支持,这可能会更好:

function pad ( num, size ) 
  if (num.toString().length >= size) return num;
  return ( Math.pow( 10, size ) + Math.floor(num) ).toString().substring( 1 );

这做了两件事:

    如果数字大于指定的大小,它将简单地返回数字。 使用Math.floor(num) 代替~~num 将支持更大的数字。

【讨论】:

pad(1111111111111, 10) 返回714581447 这是因为数字对于我原来的解决方案中使用的方法来说太大了(~~num)。为了支持更大的数字,我添加了这个函数的新版本,它使用了 Math.floor()。除此之外,您提供的数字大于您指定的大小,因此我为此场景添加了检查。 此解决方案没有用,因为 1) 仅适用于较小的大小值,2) 无法处理小数位:例如垫(0.3333,10)='0000000000'【参考方案7】:

这并不是真正的“巧妙”,但执行整数运算比为每个填充 0 执行字符串连接要快。

function ZeroPadNumber ( nValue )

    if ( nValue < 10 )
    
        return ( '000' + nValue.toString () );
    
    else if ( nValue < 100 )
    
        return ( '00' + nValue.toString () );
    
    else if ( nValue < 1000 )
    
        return ( '0' + nValue.toString () );
    
    else
    
        return ( nValue );
    

这个函数也被硬编码以满足您的特殊需要(4 位填充),所以它不是通用的。

【讨论】:

这是光滑的吗? ((x &lt; 10) ? '000' : (x &lt; 100) ? '00' : (x &lt; 1000) ? '0' : '')+(+x) @AlexChaffee 可能。 :) @Hafthor 你是把它作为一个严肃的建议发布还是只是一个玩笑?【参考方案8】:

为了好玩,不要使用循环来创建额外的零:

function zeroPad(n,length)
  var s=n+"",needed=length-s.length;
  if (needed>0) s=(Math.pow(10,needed)+"").slice(1)+s;
  return s;

【讨论】:

new Array(needed + 1).join('0') 代替昂贵的取幂怎么样? :-) 请注意,在数字转换为科学记数法之前,这仅适用于低于特定大小的长度。 Pointy 的 Array 使用通常更有效。 (@Pointy:因为这只是为了好玩:) 是的,我知道。这就像 Array 构造函数的唯一合法用途,因此值得一提:-)【参考方案9】:

既然你提到它的长度总是 4,我不会做任何错误检查来使这个光滑。 ;)

function pad(input) 
    var BASE = "0000";
    return input ? BASE.substr(0, 4 - Math.ceil(input / 10)) + input : BASE;

想法:只需将“0000”替换为提供的数字...问题是,如果input 为0,我需要对其进行硬编码以返回“0000”。哈哈。

这应该足够流畅了。

JSFiddler:http://jsfiddle.net/Up5Cr/

【讨论】:

这里有一些随机输出,证明这并不像你想象的那么流畅... bundle.js:81 023 bundle.js:81 024 bundle.js:81 025 bundle.js: 81 026 bundle.js:81 027 bundle.js:81 028 bundle.js:81 029 bundle.js:81 030 ... bundle.js:81 80 并不完美,但我喜欢这个主意。有人跳出框框思考:) ...也许将4-Math.ceil(...)部分替换为4-`$input`.length()

以上是关于在JavaScript中用前导零填充数字[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Netezza SQL 中用前导零填充整数

在 XSLT 1.0 中使用前导零填充数字

从Javascript中的数字中删除前导零[重复]

JavaScript 中前导零的数字

在Javascript中将零填充到数字的左侧[重复]

在 SQL Server 中为指定的值范围填充前导零的字符串