创建一个可变长度的字符串,填充一个重复的字符
Posted
技术标签:
【中文标题】创建一个可变长度的字符串,填充一个重复的字符【英文标题】:Create a string of variable length, filled with a repeated character 【发布时间】:2012-12-29 21:53:32 【问题描述】:所以,我的问题已被其他人以 Java 形式在这里提出:Java - Create a new String instance with specified length and filled with specific character. Best solution?
。 . .但我正在寻找它的 javascript 等价物。
基本上,我想根据每个字段的“maxlength”属性用“#”字符动态填充文本字段。因此,如果输入有maxlength="3"
,则该字段将填充“###”。
理想情况下会有类似 Java StringUtils.repeat("#", 10);
的东西,但是到目前为止,我能想到的最佳选择是循环并附加“#”字符,一次一个,直到最大长度为到达。我无法摆脱这种感觉,有比这更有效的方法。
有什么想法吗?
仅供参考 - 我不能简单地在输入中设置默认值,因为“#”字符需要清除焦点,并且,如果用户没有输入值,则需要“重新填充”模糊。这是我关心的“补充”步骤
【问题讨论】:
您这样做是为了掩盖输入字段的文本吗? @MatthewCox:不,更多的是提供最大长度的可视化显示。在这种情况下,它用于一组电话号码字段,这些字段分为号码的 3 个部分。它会显示前 2 个字段需要 3 个数字,最后一个需要 4 个。 Repeat String - Javascript的可能重复 今天可能推荐placeholder
。将此应用于所有具有maxlength
的<input>
s 看起来像document.querySelectorAll("[maxlength]").forEach((element) => element.placeholder = "#".repeat(element.maxLength));
。
【参考方案1】:
最好的方法(我见过)是
var str = new Array(len + 1).join( character );
这将创建一个具有给定长度的数组,然后将它与给定的字符串连接以重复。 .join()
函数尊重数组长度,无论元素是否分配了值,并且未定义的值呈现为空字符串。
您必须将 1 添加到所需的长度,因为分隔符字符串位于 数组元素之间。
【讨论】:
成功了。 :) 我只需要记住在输入 maxlength 值上使用parseInt()
,然后再使用它来调整数组的大小。正是我想要的。 . .谢谢!
注意,这个解决方案非常慢。它看起来很性感,但可能是完全错误的做法。
String.prototype 中内置的新 repeat
函数现在可以处理这个问题(ES6+)
病态解决方案。谢谢!【参考方案2】:
试试看:P
s = '#'.repeat(10)
document.body.innerhtml = s
【讨论】:
绝对是最简单的实现,但也是受支持最少的,因为它是 ECMAScript 6 的一部分。目前看来,它仅在 Firefox、Chrome 和桌面版 Safari 中受支持。 如果你不介意使用lodash,你可以使用下面的:_.repeat('*',10);
现在是 2018 年,ES6 已经成熟——这应该是公认的答案。如果需要为那些不使用 Babel 或类似工具的人支持旧版浏览器,您可以使用上面提到的 lodash,或者使用 polyfill 进行备份。
@seanTcoyote 尽管我很想,仍然有人不得不与 IE 11 和 Adroid 的 Webviews 抗衡,它们都不支持 repeat()
方法。期待有一天,我自己不用再关心他们了。 . .
很遗憾,不兼容IE【参考方案3】:
ES2015 最简单的方法是做类似
'X'.repeat(data.length)
X
是任意字符串,data.length
是所需长度。
见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
【讨论】:
今天阅读本文的任何人的最佳答案。【参考方案4】:不幸的是,虽然这里提到的 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;
更多信息:
Run speed test in your own browser Full source code of speed test Speed test results【讨论】:
这仍然比我的解决方案慢得多(2 到 3 个数量级)。 @Hogan 您的解决方案不会从任何地方创建填充字符串。您自己创建它,然后提取一个子字符串。 对于非常大的字符串,这种方法比 Node.js 中的 Array.join 慢 10 倍。【参考方案5】:我会创建一个常量字符串,然后在其上调用子字符串。
有点像
var hashStore = '########################################';
var Fiveup = hashStore.substring(0,5);
var Tenup = hashStore.substring(0,10);
也快一点。
http://jsperf.com/const-vs-join
【讨论】:
这很聪明!它甚至适用于包含多个字符的字符串模式。 刚刚重新访问此页面,因为它似乎一直受到很多关注并想对您的解决方案发表评论。虽然我绝对喜欢您的方法的简单性和速度,但我最关心的是维护/重用。虽然在我的特定场景中,我不需要超过 4 个字符,但作为一个通用函数,使用固定长度的字符串意味着如果您的用例需要更多字符,您必须返回并更新字符串。其他两种解决方案在这方面提供了更大的灵活性。不过,为速度 +1。 哦,另一方面(我意识到这实际上更多是一种风格问题,而不是程序化问题),维护一个 30 多个字符的字符串,该字符串只能用于 3- 4 个角色也不适合我。 . .再次,关于各种用例的解决方案灵活性的小问题。 @talemyn 在 IT 中,一切都是权衡。有一个 4 个字符的字符串,让它变大或有一个 30 个字符的字符串,不用担心。总而言之,任何大小的常量字符串——即使是 1k,在现代机器上都是很小的资源使用。 @Hogan - 完全同意。 . .而且,这实际上也是我没有特别强调速度的部分原因。在我的特定用例中,我正在寻找三个长度分别为 3、3 和 4 个字符的字符串。虽然 Pointy 的解决方案是最慢的,因为字符串很短而且只有几个,我选择了他的,因为我喜欢它流线型、易于阅读和易于维护的事实。最后,对于问题的不同变体,它们都是很好的解决方案。 . .这一切都取决于您的具体情况的优先事项。【参考方案6】:一个很好的 ES6 选项是 padStart
一个空字符串。像这样:
var str = ''.padStart(10, "#");
注意:这在 IE 中不起作用(没有 polyfill)。
【讨论】:
是否有任何理由特别推荐这种 ES6 方法而不是 @user4227915 上面的答案中的另一种方法 (s = '#'.repeat(10)
)?
仅供参考,padStart 和重复功能给出不同的结果。
太棒了,我不知道我们有这个原生方法!
@MichaelHarley 怎么样? '#'.repeat(10)===''.padStart(10, "#");
@EricLaw repeat
和 padStart
有不同的用例。对于空字符串?它'有点'一样。使用需要精确长度的字符串的动态字符串?你肯定需要padStart
或padEnd
而不是repeat
,你可以用额外的逻辑重现相同的结果。【参考方案7】:
适用于所有浏览器的版本
此功能可以满足您的需求,并且执行速度比已接受答案中建议的选项快得多:
var repeat = function(str, count)
var array = [];
for(var i = 0; i <= count;)
array[i++] = str;
return array.join('');
你这样使用它:
var repeatedCharacter = repeat("a", 10);
要将此函数的性能与已接受答案中提出的选项的性能进行比较,请参阅 this Fiddle 和 this Fiddle 以获取基准。
仅适用于现代浏览器的版本
在现代浏览器中,您现在也可以这样做:
var repeatedCharacter = "a".repeat(10) ;
这个选项甚至更快。但是,不幸的是,它不适用于任何版本的 Internet Explorer。
表中的数字表示第一个完全支持该方法的浏览器版本:
【讨论】:
在我的浏览器 (Vivaldi 2.6.1566.49 (Stable channel) (64-bit)) 中,您的解决方案所需的时间大约是接受答案的两倍。 @markuss :当我今天在最新的 Chrome 中运行基准测试时,这对我来说大致相同。请注意,我的答案已经超过 4 年了,所以性能差异可能是这 4 年中发生的更新的结果......【参考方案8】: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;
【讨论】:
【参考方案9】:基于 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)
【讨论】:
请为您的答案添加更多解释,因为代码 sn-p 本身不提供答案。 @Leandro 聪明并最大限度地减少处理! +1 我认为你的意思是 hash.length >= length【参考方案10】:如果您愿意,可以将函数的第一行用作单行:
function repeat(str, len)
while (str.length < len) str += str.substr(0, len-str.length);
return str;
【讨论】:
【参考方案11】:我愿意
Buffer.alloc(length, character).toString()
【讨论】:
【参考方案12】:如果您需要的是性能(在 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);
【讨论】:
以上是关于创建一个可变长度的字符串,填充一个重复的字符的主要内容,如果未能解决你的问题,请参考以下文章
ECMAScript6补全字符串长度方法padStart()和padEnd()