是否有一个JavaScript函数可以填充字符串以达到确定的长度?

Ant*_*tts 262 javascript string

我需要一个JavaScript函数,它可以获取一个值并将其填充到给定的长度(我需要空格,但任何事情都可以).我找到了这个:

码:

String.prototype.pad = function(l, s, t){
    return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length)
        + 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2))
        + this + s.substr(0, l - t) : this;
};
Run Code Online (Sandbox Code Playgroud)

例:

<script type="text/javascript">
//<![CDATA[

var s = "Jonas";
document.write(
    '<h2>S = '.bold(), s, "</h2>",
    'S.pad(20, "[]", 0) = '.bold(), s.pad(20, "[]", 0), "<br />",
    'S.pad(20, "[====]", 1) = '.bold(), s.pad(20, "[====]", 1), "<br />",
    'S.pad(20, "~", 2) = '.bold(), s.pad(20, "~", 2)
);

//]]>
</script>
Run Code Online (Sandbox Code Playgroud)

但我不知道它在做什么,它似乎对我不起作用.

Sam*_*uel 499

我在这里找到了这个解决方案,这对我来说简单得多:

var n = 123

String("00000" + n).slice(-5); // returns 00123
("00000" + n).slice(-5); // returns 00123
("     " + n).slice(-5); // returns "  123" (with two spaces)
Run Code Online (Sandbox Code Playgroud)

在这里,我对字符串对象进行了扩展:

String.prototype.paddingLeft = function (paddingValue) {
   return String(paddingValue + this).slice(-paddingValue.length);
};
Run Code Online (Sandbox Code Playgroud)

使用它的一个例子:

function getFormattedTime(date) {
  var hours = date.getHours();
  var minutes = date.getMinutes();

  hours = hours.toString().paddingLeft("00");
  minutes = minutes.toString().paddingLeft("00");

  return "{0}:{1}".format(hours, minutes);
};

String.prototype.format = function () {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function (match, number) {
        return typeof args[number] != 'undefined' ? args[number] : match;
    });
};
Run Code Online (Sandbox Code Playgroud)

这将返回"15:30"格式的时间

  • 请注意,此解决方案将缩短比slice参数更长的字符串(即此处为5个字符). (30认同)
  • 我发现的最容易阅读和简洁的方法; 很简单,我通常甚至不会打扰原型扩展(至少在应用程序中只有少数用途).做得好. (11认同)
  • 这非常需要更新以使用JS`String` libs`Btring.padStart()`和`String.padEnd()`进行左/右填充. (5认同)

Shy*_*ada 119

一种更快的方法

如果您反复执行此操作,例如填充数组中的值,并且性能是一个因素,则以下方法可以在速度(jsPerf)上提供近百倍的优势,而不是目前在内部网上讨论的其他解决方案.基本思想是为pad函数提供一个完全填充的空字符串,用作缓冲区.pad函数只是附加到要添加到此预填充字符串的字符串(一个字符串concat),然后将结果切片或修剪为所需长度.

function pad(pad, str, padLeft) {
  if (typeof str === 'undefined') 
    return pad;
  if (padLeft) {
    return (pad + str).slice(-pad.length);
  } else {
    return (str + pad).substring(0, pad.length);
  }
}
Run Code Online (Sandbox Code Playgroud)

例如,将数字填零为10位数,

pad('0000000000',123,true);
Run Code Online (Sandbox Code Playgroud)

要用空格填充字符串,所以整个字符串是255个字符,

var padding = Array(256).join(' '), // make a string of 255 spaces
pad(padding,123,true);
Run Code Online (Sandbox Code Playgroud)

性能测试

请参阅此处jsPerf测试.

这比ES6更快string.repeat的2倍为好,如通过修订后的JsPerf 这里

  • +1我在StackOverflow问题上的一部分原因是主持人无法根据明显优越的答案来改变选票.这是其中一个案例. (5认同)
  • 我对Jason的评论感到困惑 - 这个答案与被接受的有什么不同? (5认同)

Dav*_*vid 49

http://www.webtoolkit.info/javascript_pad.html

/**
*
*  Javascript string pad
*  http://www.webtoolkit.info/
*
**/

var STR_PAD_LEFT = 1;
var STR_PAD_RIGHT = 2;
var STR_PAD_BOTH = 3;

function pad(str, len, pad, dir) {

    if (typeof(len) == "undefined") { var len = 0; }
    if (typeof(pad) == "undefined") { var pad = ' '; }
    if (typeof(dir) == "undefined") { var dir = STR_PAD_RIGHT; }

    if (len + 1 >= str.length) {

        switch (dir){

            case STR_PAD_LEFT:
                str = Array(len + 1 - str.length).join(pad) + str;
            break;

            case STR_PAD_BOTH:
                var padlen = len - str.length;
                var right = Math.ceil( padlen / 2 );
                var left = padlen - right;
                str = Array(left+1).join(pad) + str + Array(right+1).join(pad);
            break;

            default:
                str = str + Array(len + 1 - str.length).join(pad);
            break;

        } // switch

    }

    return str;

}
Run Code Online (Sandbox Code Playgroud)

它更具可读性.

  • 当 pad 是空格时似乎不起作用: `pad("hello", 20) = "hello "` (2认同)

hyp*_*oad 39

这是一种递归方法.

function pad(width, string, padding) { 
  return (width <= string.length) ? string : pad(width, padding + string, padding)
}
Run Code Online (Sandbox Code Playgroud)

一个例子...

pad(5, 'hi', '0')
=> "000hi"
Run Code Online (Sandbox Code Playgroud)

  • 街道上还有独角鲸和一个醉汉,但两者都不相关.递归的诅咒只适用于程序员不知道何时适当的情况. (31认同)
  • "递归的诅咒只适用于程序员不知道何时适当"或当他们没有意识到这是不合适的时候.比如用于简单的字符串填充功能. (12认同)
  • 它很优雅,但它也在函数的每次迭代中创建一个新字符串.这个函数是O(n),而@Samuel最流行的解决方案是O(1).两者都很优雅,但效率更高.也就是说,这是一种简洁的方法,在不同的语言中可能会更快. (12认同)
  • 还有一个整数乘法的递归定义...总是记得在递归中有一个'诅咒'...... (7认同)

Chr*_*isV 34

String.prototype.padStart()String.prototype.padEnd()目前TC39候选人的提案:见github.com/tc39/proposal-string-pad-start-end(仅在Firefox可作为2016年4月的;一个填充工具可用).

  • 现在所有(现代)浏览器都支持:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart#Browser_compatibility (11认同)
  • 对于懒惰的人:`myString.padStart(padLength [, padString])`和`myString.padEnd(padLength [, padString])` (2认同)
  • 天哪,我怎么直到今天才听说这个?_这_应该是公认的答案。 (2认同)

arM*_*eta 24

ECMAScript 2017为String原型添加了一个padStart方法.此方法将使用空格填充给定长度的字符串.此方法还采用可选字符串,而不是空格用于填充.

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

还添加了padEnd方法,其工作方式相同.

对于浏览器兼容性(以及有用的polyfill),请参阅此链接.


Gus*_*uss 22

使用ECMAScript 6方法String#repeat,pad函数非常简单:

String.prototype.padLeft = function(char, length) { 
    return char.repeat(Math.max(0, length - this.length)) + this;
}
Run Code Online (Sandbox Code Playgroud)

String#repeat目前仅支持Firefox和Chrome.对于其他实现,可以考虑以下简单的polyfill:

String.prototype.repeat = String.prototype.repeat || function(n){ 
    return n<=1 ? this : (this + this.repeat(n-1)); 
}
Run Code Online (Sandbox Code Playgroud)


Poi*_*nty 14

这两种解决方案的关键技巧是创建一个array具有给定大小(比所需长度多一个)的实例,然后立即调用该join()方法来制作一个string.该join()方法传递填充string(可能是空格).由于array空是空的,因此strings在连接array到一个结果的过程中空单元格将呈现为空string,并且仅保留填充.这是一个非常好的技术.


Ins*_*sOp 14

使用ECMAScript 6方法String#repeatArrow函数,pad函数非常简单:

var leftPad = (s, c, n) => c.repeat(n - s.length) + s;
leftPad("foo", "0", 5); //returns "00foo"
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

编辑: 评论中的建议:

const leftPad = (s, c, n) => n - s.length > 0 ? c.repeat(n - s.length) + s : s;
Run Code Online (Sandbox Code Playgroud)

这样,当s.length大于时,它不会抛出错误n

edit2: 意见建议:

const leftPad = (s, c, n) =>{ s = s.toString(); c = c.toString(); return s.length > n ? s : c.repeat(n - s.length) + s; }
Run Code Online (Sandbox Code Playgroud)

这样,您可以将函数用于字符串和非字符串.


coc*_*cco 10

使用默认值填充

我注意到我主要需要padLeft进行时间转换/数字填充

所以我写了这个功能

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array(b||2).join(c||0)+a).slice(-b)
}
Run Code Online (Sandbox Code Playgroud)

这个简单的函数支持NumberString作为输入

默认垫是2个字符

默认char为0

所以我可以简单地写

padL(1);
// 01
Run Code Online (Sandbox Code Playgroud)

如果我添加第二个参数(垫宽)

padL(1,3);
// 001
Run Code Online (Sandbox Code Playgroud)

第三个参数(pad char)

padL('zzz',10,'x');
// xxxxxxxzzz
Run Code Online (Sandbox Code Playgroud)

编辑 @BananaAcid,如果你传递一个未定义的值或一个0长度的字符串,你得到0undefined..so:

如建议

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array((b||1)+1).join(c||0)+(a||'')).slice(-(b||2))
}
Run Code Online (Sandbox Code Playgroud)

但这也可以用更短的方式实现.

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array(b||2).join(c||0)+(a||c||0)).slice(-b)
}
Run Code Online (Sandbox Code Playgroud)

也适用于:

padL(0)
padL(NaN)
padL('')
padL(undefined)
padL(false)
Run Code Online (Sandbox Code Playgroud)

如果你想能够以两种方式填充:

function pad(a,b,c,d){//string/number,length=2,char=0,0/false=Left-1/true=Right
return a=(a||c||0),c=new Array(b||2).join(c||0),d?(a+c).slice(0,b):(c+a).slice(-b)
}
Run Code Online (Sandbox Code Playgroud)

可以在不使用切片的情况下以较短的方式编写.

function pad(a,b,c,d){
 return a=(a||c||0)+'',b=new Array((++b||3)-a.length).join(c||0),d?a+b:b+a
}
/*

Usage:

pad(
 input // (int or string) or undefined,NaN,false,empty string
       // default:0 or PadCharacter
 // optional
 ,PadLength // (int) default:2
 ,PadCharacter // (string or int) default:'0'
 ,PadDirection // (bolean) default:0 (padLeft) - (true or 1) is padRight 
)

*/
Run Code Online (Sandbox Code Playgroud)

现在,如果你尝试用2来填充'averylongword'......那不是我的问题.


说我给你一个提示.

大多数情况下,如果你填充你做相同的值N次.

在循环内使用任何类型的函数都会减慢循环!

因此,如果你只想在长列表中留下一些数字,请不要使用函数来做这个简单的事情.

使用这样的东西:

var arrayOfNumbers=[1,2,3,4,5,6,7],
    paddedArray=[],
    len=arrayOfNumbers.length;
while(len--){
 paddedArray[len]=('0000'+arrayOfNumbers[len]).slice(-4);
}
Run Code Online (Sandbox Code Playgroud)

如果您不知道基于数组内部数字的最大填充大小.

var arrayOfNumbers=[1,2,3,4,5,6,7,49095],
    paddedArray=[],
    len=arrayOfNumbers.length;

// search the highest number
var arrayMax=Function.prototype.apply.bind(Math.max,null),
// get that string length
padSize=(arrayMax(arrayOfNumbers)+'').length,
// create a Padding string
padStr=new Array(padSize).join(0);
// and after you have all this static values cached start the loop.
while(len--){
 paddedArray[len]=(padStr+arrayOfNumbers[len]).slice(-padSize);//substr(-padSize)
}
console.log(paddedArray);

/*
0: "00001"
1: "00002"
2: "00003"
3: "00004"
4: "00005"
5: "00006"
6: "00007"
7: "49095"
*/
Run Code Online (Sandbox Code Playgroud)


小智 9

接受塞缪尔的想法,在这里向上.并记住一个旧的SQL脚本,我试过这个:

a=1234;
'0000'.slice(a.toString().length)+a;
Run Code Online (Sandbox Code Playgroud)

它适用于我能想象到的所有情况:

a=     1 result  0001
a=    12 result  0012
a=   123 result  0123
a=  1234 result  1234
a= 12345 result 12345
a=  '12' result  0012
Run Code Online (Sandbox Code Playgroud)


Tan*_*ame 6

这是您可以使用的内置方法 -

str1.padStart(2, '0')
Run Code Online (Sandbox Code Playgroud)


dar*_*lff 5

填充字符串已在新的 javascript 版本中实现。

str.padStart(targetLength [, padString])

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/String/padStart

如果您想要自己的功能,请查看此示例:

const myString = 'Welcome to my house';
String.prototype.padLeft = function(times = 0, str = ' ') {
    return (Array(times).join(str) + this);
}
console.log(myString.padLeft(12, ':'));
//:::::::::::Welcome to my house
Run Code Online (Sandbox Code Playgroud)