Javascript 创建一个可变长度的字符串,填充一个重复的字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14343844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create a string of variable length, filled with a repeated character
提问by talemyn
So, my question has been asked by someone else in it's Java form here: Java - Create a new String instance with specified length and filled with specific character. Best solution?
因此,我的问题已被其他人以 Java 形式在这里提出:Java - 创建一个具有指定长度并填充特定字符的新 String 实例。最佳解决方案?
. . . but I'm looking for its JavaScript equivalent.
. . . 但我正在寻找它的 JavaScript 等价物。
Basically, I'm wanting to dynamically fill text fields with "#" characters, based on the "maxlength" attribute of each field. So, if an input has has maxlength="3", then the field would be filled with "###".
基本上,我想根据每个字段的“maxlength”属性用“#”字符动态填充文本字段。因此,如果输入具有maxlength="3",则该字段将填充为“###”。
Ideally there would be something like the Java StringUtils.repeat("#", 10);, but, so far, the best option that I can think of is to loop through and append the "#" characters, one at a time, until the max length is reached. I can't shake the feeling that there is a more efficient way to do it than that.
理想情况下会有类似 Java 的东西StringUtils.repeat("#", 10);,但到目前为止,我能想到的最佳选择是循环并附加“#”字符,一次一个,直到达到最大长度。我不能动摇有一种比这更有效的方法的感觉。
Any ideas?
有任何想法吗?
FYI - I can't simply set a default value in the input, because the "#" characters need to clear on focus, and, if the user didn't enter a value, will need to be "refilled" on blur. It's the "refill" step that I'm concerned with
仅供参考 - 我不能简单地在输入中设置默认值,因为“#”字符需要在焦点上清除,并且如果用户没有输入值,则需要在模糊时“重新填充”。这是我关心的“补充”步骤
回答by Pointy
The best way to do this (that I've seen) is
做到这一点的最好方法(我见过)是
var str = new Array(len + 1).join( character );
That creates an array with the given length, and then joins it with the given string to repeat. The .join()function honors the array length regardless of whether the elements have values assigned, and undefined values are rendered as empty strings.
这将创建一个具有给定长度的数组,然后将它与给定的字符串连接起来进行重复。.join()无论元素是否分配了值,该函数都遵循数组长度,并且未定义的值呈现为空字符串。
You have to add 1 to the desired length because the separator string goes betweenthe array elements.
您必须将 1 添加到所需的长度,因为分隔符字符串位于数组元素之间。
回答by talemyn
Give this a try :P
试试这个:P
s = '#'.repeat(10)
document.body.innerHTML = s
回答by Zero Trick Pony
Unfortunately although the Array.join approach mentioned here is terse, it is about 10X slower than a string-concatenation-based implementation. It performs especially badly on large strings. See below for full performance details.
不幸的是,虽然这里提到的 Array.join 方法很简洁,但它比基于字符串连接的实现慢了大约 10 倍。它在大字符串上的表现尤其糟糕。有关完整的性能详细信息,请参见下文。
On Firefox, Chrome, Node.js MacOS, Node.js Ubuntu, and Safari, the fastest implementation I tested was:
在 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);
};
This is verbose, so if you want a terse implementation you could go with the naive approach; it still performs betweeb 2X to 10X better than the Array.join approach, and is also faster than the doubling implementation for small inputs. Code:
这是冗长的,所以如果你想要一个简洁的实现,你可以采用天真的方法;它的性能仍然比 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;
}
Further information:
更多信息:
回答by Hogan
I would create a constant string and then call substring on it.
我会创建一个常量字符串,然后在它上面调用子字符串。
Something like
就像是
var hashStore = '########################################';
var Fiveup = hashStore.substring(0,5);
var Tenup = hashStore.substring(0,10);
A bit faster too.
也快了一点。
回答by Weeks
ES2015 the easiest way is to do something like
ES2015 最简单的方法是做类似的事情
'X'.repeat(data.length)
'X'.repeat(data.length)
Xbeing any string, data.lengthbeing the desired length.
X是任何字符串,data.length是所需的长度。
see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
请参阅:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
回答by Mendy
A great ES6 option would be to padStartan empty string. Like this:
一个很好的 ES6 选项是padStart空字符串。像这样:
var str = ''.padStart(10, "#");
Note: this won't work in IE (without a polyfill).
注意:这在 IE 中不起作用(没有 polyfill)。
回答by John Slegers
Version that works in all browsers
适用于所有浏览器的版本
This function does what you want, and performs a lot faster than the option suggested in the accepted answer :
此函数执行您想要的操作,并且执行速度比已接受的答案中建议的选项快得多:
var repeat = function(str, count) {
var array = [];
for(var i = 0; i <= count;)
array[i++] = str;
return array.join('');
}
You use it like this :
你像这样使用它:
var repeatedCharacter = repeat("a", 10);
To compare the performance of this function with that of the option proposed in the accepted answer, see this Fiddleand this Fiddlefor benchmarks.
要将此功能的性能与已接受的答案中提出的选项的性能进行比较,请参阅此 Fiddle和此 Fiddle的基准测试。
Version for moderns browsers only
仅适用于现代浏览器的版本
In modern browsers, you can now also do this :
在现代浏览器中,您现在也可以这样做:
var repeatedCharacter = "a".repeat(10) };
This option is even faster. However, unfortunately it doesn't work in any version of Internet explorer.
此选项甚至更快。但是,不幸的是它在任何版本的 Internet Explorer 中都不起作用。
The numbers in the table specify the first browser version that fully supports the method :
表中的数字指定了完全支持该方法的第一个浏览器版本:
回答by Terry Slack
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);
You can also add a polyfill for Repeat for older browsers
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;
}
}
回答by Leandro
Based on answers from Hogan and Zero Trick Pony. I think this should be both fast and flexible enough to handle well most use cases:
基于 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)
}
}
回答by Hai Phan
You can use the first line of the function as a one-liner if you like:
如果您愿意,可以将函数的第一行用作单行:
function repeat(str, len) {
while (str.length < len) str += str.substr(0, len-str.length);
return str;
}


