返回任意次数的字符串的最佳或最简洁的方法是什么?
以下是我目前为止拍得最好的照片:
function repeat(s, n){
var a = [];
while(a.length < n){
a.push(s);
}
return a.join('');
}
返回任意次数的字符串的最佳或最简洁的方法是什么?
以下是我目前为止拍得最好的照片:
function repeat(s, n){
var a = [];
while(a.length < n){
a.push(s);
}
return a.join('');
}
当前回答
扩展P.Bailey的解决方案:
String.prototype.repeat = function(num) {
return new Array(isNaN(num)? 1 : ++num).join(this);
}
这样你就可以避免意外的参数类型:
var foo = 'bar';
alert(foo.repeat(3)); // Will work, "barbarbar"
alert(foo.repeat('3')); // Same as above
alert(foo.repeat(true)); // Same as foo.repeat(1)
alert(foo.repeat(0)); // This and all the following return an empty
alert(foo.repeat(false)); // string while not causing an exception
alert(foo.repeat(null));
alert(foo.repeat(undefined));
alert(foo.repeat({})); // Object
alert(foo.repeat(function () {})); // Function
编辑:感谢jerone为他优雅的++num想法!
其他回答
如果您认为所有这些原型定义、数组创建和连接操作都是多余的,那么只需在需要的地方使用一行代码。字符串S重复N次:
for (var i = 0, result = ''; i < N; i++) result += S;
要在指定次数内重复一个字符串,可以使用JavaScript中内置的repeat()方法。
下面是一个重复以下字符串4次的例子:
const name = "king";
const repeat = name.repeat(4);
console.log(repeat);
输出:
"kingkingkingking"
或者我们可以创建自己版本的repeat()函数,如下所示:
function repeat(str, n) {
if (!str || !n) {
return;
}
let final = "";
while (n) {
final += s;
n--;
}
return final;
}
console.log(repeat("king", 3))
(最初发布于https://reactgo.com/javascript-repeat-string/)
我已经测试了所有提议的方法的性能。
这是我找到的最快的变种。
String.prototype.repeat = function(count) {
if (count < 1) return '';
var result = '', pattern = this.valueOf();
while (count > 1) {
if (count & 1) result += pattern;
count >>= 1, pattern += pattern;
}
return result + pattern;
};
或作为独立函数:
function repeat(pattern, count) {
if (count < 1) return '';
var result = '';
while (count > 1) {
if (count & 1) result += pattern;
count >>= 1, pattern += pattern;
}
return result + pattern;
}
它基于wnrph算法。 它真的很快。与传统的Array(count + 1).join(string)方法相比,计数越大,它的运行速度就越快。
我只改变了两件事:
replace pattern = this with pattern = this. valueof()(清除一个明显的类型转换); 增加if (count < 1)检查从prototypejs到函数的顶部,以排除在这种情况下不必要的操作。 应用优化从丹尼斯的答案(5-7%的速度提高)
UPD
为感兴趣的人准备了一个性能测试场地。
变量计数~ 0 ..100:
常量= 1024:
如果可以的话,使用它,让它更快:)
我随机来到这里,从来没有理由在javascript中重复字符。
我对artistoex的做法印象深刻,对结果感到失望。我注意到最后一个串连接是不必要的,正如丹尼斯也指出的那样。
我注意到一些更多的东西,当玩抽样disfate放在一起。
The results varied a fair amount often favoring the last run and similar algorithms would often jockey for position. One of the things I changed was instead of using the JSLitmus generated count as the seed for the calls; as count was generated different for the various methods, I put in an index. This made the thing much more reliable. I then looked at ensuring that varying sized strings were passed to the functions. This prevented some of the variations I saw, where some algorithms did better at the single chars or smaller strings. However the top 3 methods all did well regardless of the string size.
分叉测试集
http://jsfiddle.net/schmide/fCqp3/134/
// repeated string
var string = '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
// count paremeter is changed on every test iteration, limit it's maximum value here
var maxCount = 200;
var n = 0;
$.each(tests, function (name) {
var fn = tests[name];
JSLitmus.test(++n + '. ' + name, function (count) {
var index = 0;
while (count--) {
fn.call(string.slice(0, index % string.length), index % maxCount);
index++;
}
});
if (fn.call('>', 10).length !== 10) $('body').prepend('<h1>Error in "' + name + '"</h1>');
});
JSLitmus.runAll();
然后我加入了丹尼斯的解决方案,并决定看看我是否能找到更多的方法。
由于javascript不能真正优化,提高性能的最好方法是手动避免一些东西。如果我把前4个琐碎的结果从循环中取出,我可以避免2-4个字符串存储,并将最后的存储直接写入结果。
// final: growing pattern + prototypejs check (count < 1)
'final avoid': function (count) {
if (!count) return '';
if (count == 1) return this.valueOf();
var pattern = this.valueOf();
if (count == 2) return pattern + pattern;
if (count == 3) return pattern + pattern + pattern;
var result;
if (count & 1) result = pattern;
else result = '';
count >>= 1;
do {
pattern += pattern;
if (count & 1) result += pattern;
count >>= 1;
} while (count > 1);
return result + pattern + pattern;
}
这比丹尼斯的修复方案平均提高了1-2%。然而,不同的运行和不同的浏览器会显示相当大的差异,这额外的代码可能不值得在前面的两种算法上付出努力。
一个图表
编辑:我这样做主要是在chrome浏览器。Firefox和IE通常对Dennis的偏爱程度为百分之几。
扩展P.Bailey的解决方案:
String.prototype.repeat = function(num) {
return new Array(isNaN(num)? 1 : ++num).join(this);
}
这样你就可以避免意外的参数类型:
var foo = 'bar';
alert(foo.repeat(3)); // Will work, "barbarbar"
alert(foo.repeat('3')); // Same as above
alert(foo.repeat(true)); // Same as foo.repeat(1)
alert(foo.repeat(0)); // This and all the following return an empty
alert(foo.repeat(false)); // string while not causing an exception
alert(foo.repeat(null));
alert(foo.repeat(undefined));
alert(foo.repeat({})); // Object
alert(foo.repeat(function () {})); // Function
编辑:感谢jerone为他优雅的++num想法!