在 JavaScript 中用前导零填充数字

IT技术 javascript formatting
2021-01-23 12:57:53

在 JavaScript 中,我需要填充。

例如,如果我有数字 9,它将是“0009”。如果我有一个数字说 10,它将是“0010”。请注意它如何始终包含四位数字。

一种方法是减去负 4 的数字以获得我需要放置的 0 的数量。

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

6个回答

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

类似的东西?

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

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

ES6isms:

  • let是块范围变量(与var的功能范围相反
  • =>是一个箭头函数,除其他外function,它替换并附加了它的参数
  • 如果箭头函数采用单个参数,则可以省略括号(因此number =>
  • 如果箭头函数体有一行以开头,return您可以省略大括号和return关键字,只需使用表达式
  • 为了将函数体缩减为一行,我欺骗并使用了三元表达式
只投了反对票,因为这不是module化方法(仅适用于 4 位数字)。当然,这是对特定问题的特定答案,但包含长度选项会更好(与其他答案一样)。
2021-03-11 12:57:53
我喜欢切片的用法。但是,正如@doubleJ 提到的,请注意这种方法的一个限制是会将数字截断为最后 4 位数字。
2021-03-13 12:57:53
我认为我们已经取得了倒退的进展 sprintf (padToFour, "%04d", number);
2021-03-14 12:57:53
实际上@JorgeOrpinel 它不会截断。if 语句导致切片操作仅对具有四位或更少位数的数字进行操作。五位数字的值至少为 10000,即不 <= 9999。
2021-03-24 12:57:53
这很简单,但不是那么新颖;我最近不得不做类似的事情,并在网上找到了这种方法。
2021-04-02 12:57:53

尝试:

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不止一个符号的情况。
2021-03-13 12:57:53
+1 指出 ES8 解决方案。这里描述了一个简单的polyfill2ality.com/2015/11/string-padding.html
2021-03-29 12:57:53
你这样做的方式,"5".lpad("--", 4)将产生“ ----5”而不是“ ---5”。
2021-04-01 12:57:53
ES8 解决方案现在应该是解决这个问题的答案。你应该把它放在你的答案的顶部。
2021-04-04 12:57:53
不建议像任何其他内置函数一样扩展 String 原型。
2021-04-05 12:57:53

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

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)
2021-03-17 12:57:53
我非常喜欢这个解决方案@NeilMonroe,但你愿意为我们分解它吗?作为评论,它的可读性不是很强。:)
2021-03-26 12:57:53
写了一个类似的答案,我首先将 num 转换为 str 并使用return (Array(Math.max(5-str.length, 0)).join("0") + str);,只是删除它以防其他 Q 被删除
2021-04-05 12:57:53
要处理负数,请使用该数的绝对值,然后在最终结果上加上一个负号 ('-')。(number < 0 ? '-' : '') + Array(Math.max(digits - String(value).length + 1, 0)).join(0) + value“value”在哪里Math.abs(number)
2021-04-09 12:57:53

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

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'
2021-03-11 12:57:53
也刚刚意识到降价的四个空格在这些评论字段中不起作用
2021-03-14 12:57:53
我一直在寻找用前导零填充,这是我选择的解决方案。应该多点赞。
2021-03-16 12:57:53
因为这个解决方案太具体了... ``` String.prototype.lpad = function(len, c){ var s= '', c= c || ' ', len= (len || 2)-this.length; while(s.length<len) s+= c; 返回 s+this; } Number.prototype.lpad = function(len, c){ return String(this).lpad(len, c); } Number.prototype.lpadZero = function(len) { return this.lpad(len,'0'); } ``` 是一个更清晰的解决方案,因为它是可预测的;如果错误地使用了pad,它会产生较少的效果驱动结果,它只是添加了不影响可读性或可访问性的空格
2021-03-29 12:57:53