200

所以,我的问题已被其他人以 Java 形式提出:Java - 创建一个具有指定长度并填充特定字符的新字符串实例。最佳解决方案?

. . . 但我正在寻找它的 JavaScript 等价物。

基本上,我想根据每个字段的“maxlength”属性用“#”字符动态填充文本字段。因此,如果输入 has maxlength="3",则该字段将填充“###”。

理想情况下会有类似 Java 的东西StringUtils.repeat("#", 10);,但是到目前为止,我能想到的最好的选择是循环并附加“#”字符,一次一个,直到达到最大长度。我无法摆脱比这更有效的方法的感觉。

有任何想法吗?

仅供参考 - 我不能简单地在输入中设置默认值,因为“#”字符需要清除焦点,并且如果用户没有输入值,则需要在模糊时“重新填充”。这是我关心的“补充”步骤

4

12 回答 12

352

最好的方法(我见过)是

var str = new Array(len + 1).join( character );

这将创建一个具有给定长度的数组,然后将其与给定的字符串连接以重复。.join()无论元素是否分配了值,该函数都会尊重数组长度,并且未定义的值将呈现为空字符串。

您必须将 1 添加到所需的长度,因为分隔符字符串位于数组元素之间。

于 2013-01-15T17:59:54.493 回答
229

试试这个:P

s = '#'.repeat(10)

document.body.innerHTML = s

于 2016-01-15T12:44:37.267 回答
37

ES2015 最简单的方法是做类似的事情

'X'.repeat(data.length)

X是任何字符串,data.length是所需的长度。

见:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

于 2018-10-05T17:13:57.520 回答
31

不幸的是,虽然这里提到的 Array.join 方法很简洁,但它比基于字符串连接的实现慢了大约 10 倍。它在大字符串上表现特别差。有关完整的性能详细信息,请参见下文。

在 Firefox、Chrome、Node.js MacOS、Node.js Ubuntu 和 Safari 上,我测试的最快实现是:

function repeatChar(count, ch) {
    if (count == 0) {
        return "";
    }
    var count2 = count / 2;
    var result = ch;

    // double the input until it is long enough.
    while (result.length <= count2) {
        result += result;
    }
    // use substring to hit the precise length target without
    // using extra memory
    return result + result.substring(0, count - result.length);
};

这是冗长的,所以如果你想要一个简洁的实现,你可以使用幼稚的方法;它的性能仍然比 Array.join 方法好 2 到 10 倍,并且也比小输入的加倍实现更快。代码:

// naive approach: simply add the letters one by one
function repeatChar(count, ch) {
    var txt = "";
    for (var i = 0; i < count; i++) {
        txt += ch;
    }
    return txt;
}

更多信息:

于 2014-01-27T01:33:33.420 回答
24

我会创建一个常量字符串,然后在其上调用子字符串。

就像是

var hashStore = '########################################';

var Fiveup = hashStore.substring(0,5);

var Tenup = hashStore.substring(0,10);

也快一点。

http://jsperf.com/const-vs-join

于 2013-03-09T05:23:26.690 回答
11

一个很好的 ES6 选项是padStart空字符串。像这样:

var str = ''.padStart(10, "#");

注意:这在 IE 中不起作用(没有 polyfill)。

于 2018-06-07T15:48:17.743 回答
4

适用于所有浏览器的版本

此功能可以满足您的需求,并且执行速度比已接受答案中建议的选项快得多:

var repeat = function(str, count) {
    var array = [];
    for(var i = 0; i <= count;)
        array[i++] = str;
    return array.join('');
}

你像这样使用它:

var repeatedCharacter = repeat("a", 10);

要将此功能的性能与已接受答案中提出的选项的性能进行比较,请参阅此 Fiddle此 Fiddle以获取基准。

仅适用于现代浏览器的版本

在现代浏览器中,您现在也可以这样做:

var repeatedCharacter = "a".repeat(10) };

这个选项甚至更快。但是,不幸的是,它在任何版本的 Internet Explorer 中都不起作用。

表中的数字指定了完全支持该方法的第一个浏览器版本:

在此处输入图像描述

于 2016-02-25T18:42:52.280 回答
3
For Evergreen browsers, this will build a staircase based on an incoming character and the number of stairs to build.
function StairCase(character, input) {
    let i = 0;
    while (i < input) {
        const spaces = " ".repeat(input - (i+1));
        const hashes = character.repeat(i + 1);
        console.log(spaces + hashes);
        i++;
    }
}

//Implement
//Refresh the console
console.clear();
StairCase("#",6);   

您还可以为旧浏览器的重复添加 polyfill

    if (!String.prototype.repeat) {
      String.prototype.repeat = function(count) {
        'use strict';
        if (this == null) {
          throw new TypeError('can\'t convert ' + this + ' to object');
        }
        var str = '' + this;
        count = +count;
        if (count != count) {
          count = 0;
        }
        if (count < 0) {
          throw new RangeError('repeat count must be non-negative');
        }
        if (count == Infinity) {
          throw new RangeError('repeat count must be less than infinity');
        }
        count = Math.floor(count);
        if (str.length == 0 || count == 0) {
          return '';
        }
        // Ensuring count is a 31-bit integer allows us to heavily optimize the
        // main part. But anyway, most current (August 2014) browsers can't handle
        // strings 1 << 28 chars or longer, so:
        if (str.length * count >= 1 << 28) {
          throw new RangeError('repeat count must not overflow maximum string size');
        }
        var rpt = '';
        for (;;) {
          if ((count & 1) == 1) {
            rpt += str;
          }
          count >>>= 1;
          if (count == 0) {
            break;
          }
          str += str;
        }
        // Could we try:
        // return Array(count + 1).join(this);
        return rpt;
      }
    } 
于 2016-11-02T22:06:47.733 回答
3

基于 Hogan 和 Zero Trick Pony 的回答。我认为这应该既快速又灵活,可以很好地处理大多数用例:

var hash = '####################################################################'

function build_string(length) {  
    if (length == 0) {  
        return ''  
    } else if (hash.length <= length) {  
        return hash.substring(0, length)  
    } else {  
        var result = hash  
        const half_length = length / 2  
        while (result.length <= half_length) {  
            result += result  
        }  
        return result + result.substring(0, length - result.length)  
    }  
}  
于 2017-04-25T15:06:28.110 回答
1

如果您愿意,可以将函数的第一行用作单行:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}
于 2017-05-14T16:24:56.787 回答
0

如果它是您需要的性能(在 ES6 之前),那么 substr 和模板字符串的组合可能是最好的。这个函数是我用来创建空格填充字符串的,但你可以将模板更改为你需要的任何内容:

function strRepeat(intLen, strTemplate) {
  strTemplate = strTemplate || "          ";
  var strTxt = '';
  while(intLen > strTemplate.length) {
    strTxt += strTemplate;
    intLen -= strTemplate.length;
  }
  return ((intLen > 0) ? strTxt + strTemplate.substr(0, intLen) : strTxt);
}
于 2021-07-27T09:35:27.163 回答
0

我会做

Buffer.alloc(length, character).toString()
于 2021-04-15T13:56:49.500 回答