在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
的函数作用域相反)
=>
是一个箭头函数,除其他外替换 function
并由其参数前置
如果箭头函数采用单个参数,您可以省略括号(因此number =>
)
如果箭头函数体有一行以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 中,我们有新方法 padStart
和 padEnd
具有以下语法。
"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 < 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你可以这样做:
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 < 10) ? '000' : (x < 100) ? '00' : (x < 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中用前导零填充数字[重复]的主要内容,如果未能解决你的问题,请参考以下文章