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

IT技术 javascript string
2021-01-31 01:38:09

我需要一个 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;
};



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)
);

6个回答

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

var n = 123

String("00000" + n).slice(-5); // returns 00123
("00000" + n).slice(-5); // returns 00123
("     " + n).slice(-5); // returns "  123" (with two spaces)

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

String.prototype.paddingLeft = function (paddingValue) {
   return String(paddingValue + this).slice(-paddingValue.length);
};

一个使用它的例子:

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;
    });
};

这将返回格式为“15:30”的时间

嗨,雅尼夫。你有一个很好的建议来修改算法。然而,就我而言,要求总是先于这个问题,因为当我尝试格式化某些东西时,我总是有关于我必须处理的值的最低限度的规范,在这种情况下,规范将纠正这个问题。例如,如果我有一个电话号码要格式化并且我只在加拿大处理电话,我将在格式化之前验证该电话号码是否有 10 个字符。在任何情况下,您的解决方案也很棒。:)
2021-03-11 01:38:09
如果您经常这样做(例如在您的页面或其他应用程序上的某种列表中填充一长串值),还可以stackoverflow.com/questions/2686855/ 上使用更快的方法查看答案...
2021-03-20 01:38:09
我发现的最易读和最简洁的方法很容易;足够简单,我通常甚至不会打扰原型扩展(至少在应用程序中仅用于少数用途)。做得好。
2021-03-31 01:38:09
这非常需要更新以使用 JSStringString.padStart()String.padEnd()左/右填充。
2021-04-03 01:38:09
请注意,此解决方案将缩短比 slice 参数(即此处为 5 个字符)长的字符串。
2021-04-09 01:38:09

更快的方法

如果您重复执行此操作,例如填充数组中的值,并且性能是一个因素,那么与当前在互联网上讨论的其他解决方案相比以下方法可以为您提供近100 倍的速度优势( 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);
  }
}

例如,要将一个数字零填充到 10 位数字的长度,

pad('0000000000',123,true);

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

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

性能测试

请参阅此处jsPerf测试

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

请注意jsPerf不再在线

请注意,我们最初用于对各种方法进行基准测试的 jsPerf 站点已不再在线。不幸的是,这意味着我们无法获得这些测试结果。悲伤但真实。

正如其他人在后来的 jsPerf(上面添加的链接)中证明的那样,这种方法比 ES6string.repeat方法快约 2 倍因此,如果您要进行大量字符串填充,请务必尝试此操作。
2021-03-14 01:38:09
我对这种方法的唯一观察是,如果实际str长度大于pad长度,那么输出将在最后被截断。意味着str将返回的长度为pad这可能不是预期或预期的行为。
2021-03-27 01:38:09
我看了你的jsPerf。这些测试适用于您的函数和使用 while() 循环的东西,其他高评分答案都没有使用它。我不确定这是否意味着它更快?
2021-03-29 01:38:09
我对杰森的评论感到困惑——这个答案与公认的有什么不同?
2021-04-01 01:38:09
+1 我对 StackOverflow 的部分问题是版主无法根据明显优越的答案更改投票。这是其中一种情况。
2021-04-03 01:38:09

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

对于懒人:myString.padStart(padLength [, padString])myString.padEnd(padLength [, padString])
2021-04-02 01:38:09
现在所有(现代)浏览器都支持:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-06 01:38:09
天哪,我怎么直到今天才听说过这个??应该是公认的答案。
2021-04-08 01:38:09
请添加一些示例用法,现在所有现代浏览器都支持它。应该鼓励这种做法。
2021-04-10 01:38:09

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;

}

它更具可读性。

当 pad 是空格时似乎不起作用: pad("hello", 20) = "hello "
2021-04-02 01:38:09

这是一个递归的方法。

function pad(width, string, padding) { 
  return (width <= string.length) ? string : pad(width, padding + string, padding)
}

一个例子...

pad(5, 'hi', '0')
=> "000hi"
这非常优雅,非常适合我的用例。如果您需要填充空格以对齐文本,只需输入最长字符串的长度 =)
2021-03-15 01:38:09
“递归诅咒只在程序员不知道什么时候合适时才适用”或者当他们没有意识到它是不合适的时候。比如一个简单的字符串pad函数。
2021-03-17 01:38:09
街上也有独角鲸和醉汉,但两者都无关紧要。递归诅咒只适用于程序员不知道什么时候合适的情况。
2021-03-24 01:38:09
还有一个整数乘法的递归定义......永远记住递归中有一个“诅咒”......
2021-04-01 01:38:09
它很优雅,但它也会在函数的每次迭代中创建一个新字符串。这个函数是 O(n) 而@Samuel 最流行的解决方案是 O(1)。两者都很优雅,但一个效率更高。也就是说,这是一种巧妙的方法,并且在不同的语言中可能会更快。
2021-04-09 01:38:09