Каков наилучший или наиболее краткий способ возврата строки, повторяющейся произвольное количество раз?
Вот мой лучший снимок на данный момент:
function repeat(s, n){
var a = [];
while(a.length < n){
a.push(s);
}
return a.join('');
}
Попробуйте это сравнение и подумайте об изменении принятого ответа на существующее давнее решение этой проблемы, опубликованное до того, как этот вопрос когда-либо был задан. jsperf.com/repeating-strings
Никто не поднял решение Джозефа. Алгоритм 3700 лет. Стоимость дополнительной ступеньки ничтожна. А эта статья содержит ошибки и заблуждения относительно конкатенации строк в Javascript. Для всех, кто интересуется тем, как Javascript действительно обрабатывает строки внутри, см. Веревка.
Кажется, никто не заметил, что повторение прототипа String определено и реализовано, по крайней мере, в firefox.
@kennebec: Да, это функция EcmaScript 6, которой не было, когда задавали этот вопрос. Сейчас он довольно хорошо поддерживается.
@rvighne - я только что проверил kangax.github.io/compat-table/es6/#String.prototype.repeat, я бы не стал считать поддержку исключительно из firefox и chrome "достаточно хорошо поддерживаемой"
Как говорится в комментарии Кеннебека и в ответе Андре Ласло для ES6: 'mystring'.repeat(xTimes)
@brad Не могли бы вы изменить принятый ответ на Вот этот, пожалуйста?
Конечно! Поменял только сейчас.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


function repeat(s, n) { var r = ""; for (var a=0;a<n;a++) r+=s; return r;}
Разве конкатенация строк не требует больших затрат? По крайней мере, так обстоит дело с Java.
Почему да, они есть. Однако его нельзя оптимизировать в javascript. :(
Как насчет этого повышения производительности: var r=s; for (var a=1;... :)))) В любом случае, согласно этому тесту (jsperf.com/string-repeat/2) выполнение простого цикла for с объединением строк, как то, что вы предложили, кажется намного быстрее в Chrome по сравнению с использованием Array.join.
@VijayDev - не по этому тесту: jsperf.com/ultimate-concat-vs-join
Note to new readers: This answer is old and and not terribly practical - it's just "clever" because it uses Array stuff to get String things done. When I wrote "less process" I definitely meant "less code" because, as others have noted in subsequent answers, it performs like a pig. So don't use it if speed matters to you.
Я бы поместил эту функцию непосредственно в объект String. Вместо того, чтобы создавать массив, заполнять его и присоединять к нему пустым символом, просто создайте массив надлежащей длины и соедините его с желаемой строкой. Тот же результат, меньше процесса!
String.prototype.repeat = function( num )
{
return new Array( num + 1 ).join( this );
}
alert( "string to repeat\n".repeat( 4 ) );
Я стараюсь не расширять нативные объекты, но в остальном это прекрасное решение. Спасибо!
Это очень умно. Я не могу дождаться возможности воспользоваться им.
@ brad - а почему бы и нет? Вы бы предпочли загрязнить глобальное пространство имен функцией, у которой есть довольно четко определенный дом (объект String)?
BaileyP: Расширение встроенных объектов ломает вещи. В случае строки это не так уж плохо, но для массива и т. д. Вы создаете проблемы
Что, если кто-то еще захочет определить String.repeat для чего-то другого? Может быть, это в библиотеке, которую вы используете, или, может быть, в другом программисте в вашей команде. Бывает.
Фактически, оба ваших аргумента применимы и к глобальному пространству имен. Если я собираюсь расширить пространство имен и иметь потенциальные коллизии, я бы предпочел сделать это 1) не в глобальном, 2) в релевантном и 3) легко реорганизовать. Это означает размещение его в прототипе String, а не в global.
одно изменение, которое я внесу в эту функцию, заключалось бы в том, чтобы поместить parseInt () вокруг «num», поскольку, если у вас есть числовая строка, вы можете получить странное поведение из-за манипулирования типами JS. например: "моя строка" .repeat ("6") == "61"
Если вы не хотите расширять собственные объекты, вы можете вместо этого поместить функцию в объект String, например: String.repeat = function(string, num){ return new Array(parseInt(num) + 1).join(string); };. Назовите это так: String.repeat('/\', 20)
@nickf: Люди не должны передавать строки функциям, ожидающим числа.
Если вы собираетесь использовать parseInt, используйте систему счисления (parseInt(num, 10)); в противном случае вы получите неприятный сюрприз, если в num в начале будет 0 (он будет проанализирован как восьмеричный). В идеале просто используйте + num (new Array(+num + 1)).
Версия CoffeeScript: String::repeat = (n) -> new Array(n + 1).join @
Или num | 0, если мы говорим о синтаксическом разборе int из строк и споре типов javascript. Однако, поскольку несколько других функций в типе js проверяют аргументы, я действительно не вижу в этом смысла. Не отправляйте строку в функцию, которая требует числа.
Это действительно плохо
Просто случайный Вау. @LourenzoFerreira: Что ты имеешь в виду? Пожалуйста, будьте конструктивны, спасибо.
Я попытался упростить эту функцию, и в результате получилось: return [](+num).join(this);
@ JesúsOtero Мне это не кажется "упрощенным", просто короче. Намного труднее понять, что делает код.
Просто ПРИМЕЧАНИЕ: Array.join () в несколько раз медленнее, чем даже подходы грубой силы, указанные ниже: Disfated, безусловно, имеет самый надежный ответ как с точки зрения скорости, так и с точки зрения потребления памяти и неиспользования рекурсии. (поскольку высота стека может стать невообразимо большой), а array.join создает копии при копиях подстрок, а также при вызовах внутренних функций.
Красиво, иногда простота и удобочитаемость важнее производительности.
/**
@desc: repeat string
@param: n - times
@param: d - delimiter
*/
String.prototype.repeat = function (n, d) {
return --n ? this + (d || '') + this.repeat(n, d) : '' + this
};
вот как повторить строку несколько раз, используя разделитель.
Расширение Решение П. Бейли:
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
Обновлено: Благодарим Джерон за его элегантную идею ++num!
Немного изменил ваш: String.prototype.repeat = function(n){return new Array(isNaN(n) ? 1 : ++n).join(this);}
В любом случае, согласно этому тесту (jsperf.com/string-repeat/2) выполнение простого цикла for с объединением строк кажется намного быстрее в Chrome по сравнению с использованием Array.join. Разве это не смешно ?!
Это довольно эффективно
String.prototype.repeat = function(times){
var result = "";
var pattern=this;
while (times > 0) {
if (times&1)
result+=pattern;
times>>=1;
pattern+=pattern;
}
return result;
};
@Olegs, я думаю, что идея голосования меньше, чем голосование за человека или за творчество человека (что действительно приветствуется), но идея состоит в том, чтобы проголосовать за наиболее полное решение, чтобы его можно было легко найти на вверху списка, без необходимости читать все ответы в поисках идеального. (Потому что, к сожалению, у всех нас мало времени ...)
Я протестировал работоспособность всех предложенных подходов.
Вот самый быстрый вариант у меня есть.
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;
}
Он основан на алгоритме Artistoex.
Это действительно быстро. И чем больше count, тем быстрее он движется по сравнению с традиционным подходом new Array(count + 1).join(string).
Я изменил только 2 вещи:
pattern = this на pattern = this.valueOf() (устраняет одно очевидное преобразование типа);if (count < 1) из prototypejs в начало функции, чтобы исключить ненужные действия в этом случае.UPD
Для желающих создана небольшая площадка для тестирования производительности здесь.
переменная count ~ 0 .. 100:
константа count = 1024:
Используйте это и сделайте это еще быстрее, если сможете :)
Хорошо сделано! Считаю, что корпус count < 1 действительно лишняя оптимизация.
Отличный алгоритм O (log N). Спасибо за отличную оптимизацию с помощью valueOf ()
Ссылки на изображения мертвы.
Ссылки в порядке. Может быть временная недоступность
Тестовый JSFiddle больше не работает правильно; кажется, он просто запускает первую функцию снова и снова (оставил ее работать на полчаса, чтобы быть уверенным)
Это может быть самый маленький рекурсивный: -
String.prototype.repeat = function(n,s) {
s = s || ""
if (n>0) {
s += this
s = this.repeat(--n,s)
}
return s}
Рекурсивное решение с использованием разделяй и властвуй:
function repeat(n, s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
with(Math) { return repeat(floor(n/2), s)+repeat(ceil(n/2), s); }
}
Испытания различных методов:
var repeatMethods = {
control: function (n,s) {
/* all of these lines are common to all methods */
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
return '';
},
divideAndConquer: function (n, s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
with(Math) { return arguments.callee(floor(n/2), s)+arguments.callee(ceil(n/2), s); }
},
linearRecurse: function (n,s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
return s+arguments.callee(--n, s);
},
newArray: function (n, s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
return (new Array(isNaN(n) ? 1 : ++n)).join(s);
},
fillAndJoin: function (n, s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
var ret = [];
for (var i=0; i<n; i++)
ret.push(s);
return ret.join('');
},
concat: function (n,s) {
if (n==0) return '';
if (n==1 || isNaN(n)) return s;
var ret = '';
for (var i=0; i<n; i++)
ret+=s;
return ret;
},
artistoex: function (n,s) {
var result = '';
while (n>0) {
if (n&1) result+=s;
n>>=1, s+=s;
};
return result;
}
};
function testNum(len, dev) {
with(Math) { return round(len+1+dev*(random()-0.5)); }
}
function testString(len, dev) {
return (new Array(testNum(len, dev))).join(' ');
}
var testTime = 1000,
tests = {
biggie: { str: { len: 25, dev: 12 }, rep: {len: 200, dev: 50 } },
smalls: { str: { len: 5, dev: 5}, rep: { len: 5, dev: 5 } }
};
var testCount = 0;
var winnar = null;
var inflight = 0;
for (var methodName in repeatMethods) {
var method = repeatMethods[methodName];
for (var testName in tests) {
testCount++;
var test = tests[testName];
var testId = methodName+':'+testName;
var result = {
id: testId,
testParams: test
}
result.count=0;
(function (result) {
inflight++;
setTimeout(function () {
result.start = +new Date();
while ((new Date() - result.start) < testTime) {
method(testNum(test.rep.len, test.rep.dev), testString(test.str.len, test.str.dev));
result.count++;
}
result.end = +new Date();
result.rate = 1000*result.count/(result.end-result.start)
console.info(result);
if (winnar === null || winnar.rate < result.rate) winnar = result;
inflight--;
if (inflight==0) {
console.info('The winner: ');
console.info(winnar);
}
}, (100+testTime)*testCount);
}(result));
}
}
Вот безопасная версия JSLint
String.prototype.repeat = function (num) {
var a = [];
a.length = num << 0 + 1;
return a.join(this);
};
Вот 5-7% улучшение по сравнению с ответом disfated.
Разверните цикл, остановившись на count > 1, и выполните дополнительное объединение result += pattnern после цикла. Это позволит избежать зацикливания завершающего ранее неиспользованного pattern += pattern без необходимости использовать дорогостоящую if-check.
Окончательный результат будет выглядеть так:
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;
}
result += pattern;
return result;
};
И вот раздвоенная рабочий пример, разветвленная для развернутой версии: http://jsfiddle.net/wsdfg/
Если вы думаете, что все эти определения прототипов, создание массивов и операции соединения излишни, просто используйте однострочный код там, где он вам нужен. Строка S повторяется N раз:
for (var i = 0, result = ''; i < N; i++) result += S;
Код должен быть читабельным. Если вы буквально каждый раз собираетесь использовать его только один раз, отформатируйте его должным образом (или используйте метод Array(N + 1).join(str), если это не является узким местом для производительности). Если есть малейшая вероятность, что вы собираетесь использовать его дважды, переместите его в функцию с соответствующим именем.
Я пришел сюда случайно, и раньше у меня не было причин повторять char в javascript.
На меня произвело впечатление то, как artistoex это сделала, и разочаровал результаты. Я заметил, что последняя строка concat не нужна, как также указал Деннис.
Я заметил еще несколько вещей, играя с дискредитированным сэмплом вместе взятым.
Результаты сильно различались, часто в пользу последнего прогона, и аналогичные алгоритмы часто пытались занять позицию. Одна из вещей, которые я изменил, заключалась в том, что вместо использования сгенерированного JSLitmus счетчика в качестве начального числа для вызовов; поскольку счетчик генерировался по-разному для разных методов, я добавил индекс. Это сделало вещь намного более надежной. Затем я посмотрел на то, чтобы в функции передавались строки разного размера. Это предотвратило некоторые из вариаций, которые я видел, когда некоторые алгоритмы лучше работали с одиночными символами или меньшими строками. Однако все 3 лучших метода хорошо себя зарекомендовали, независимо от размера строки.
Раздвоенный тестовый набор
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% по сравнению с исправлением Денниса. Тем не менее, разные прогоны и разные браузеры будут показывать достаточно справедливую дисперсию, так что этот дополнительный код, вероятно, не стоит усилий по сравнению с двумя предыдущими алгоритмами.
Обновлено: я делал это в основном под хромом. Firefox и IE часто на пару процентов отдают предпочтение Деннису.
Простой способ:
String.prototype.repeat = function(num) {
num = parseInt(num);
if (num < 0) return '';
return new Array(num + 1).join(this);
}
Рабочий пример: http://jsfiddle.net/3Y9v2/
function repeat(s, n){
return ((new Array(n+1)).join(s));
}
alert(repeat('R', 10));
Люди чрезмерно усложняют это до смехотворной степени или тратят зря производительность. Массивы? Рекурсия? Ты меня разыгрываешь.
function repeat (string, times) {
var result = ''
while (times-- > 0) result += string
return result
}
Редактировать. Я провел несколько простых тестов для сравнения с побитовой версией, опубликованной artistoex / disfated и другими людьми. Последний был лишь ненамного быстрее, но на несколько порядков эффективнее с памятью. Для 1000000 повторений слова «бла» процесс Node увеличился до 46 мегабайт с помощью простого алгоритма конкатенации (см. Выше), но только 5,5 мегабайт с помощью логарифмического алгоритма. Последнее, безусловно, лучший вариант. Репост для ясности:
function repeat (string, times) {
var result = ''
while (times > 0) {
if (times & 1) result += string
times >>= 1
string += string
}
return result
}
В половине случаев у вас есть резервный string += string.
Я просто хотел дать ему удар, и сделал это:
function ditto( s, r, c ) {
return c-- ? ditto( s, r += s, c ) : r;
}
ditto( "foo", "", 128 );
Не могу сказать, что я много думал об этом, и это, наверное, видно :-)
String.prototype.ditto = function( c ) {
return --c ? this + this.ditto( c ) : this;
};
"foo".ditto( 128 );
И это очень похоже на уже опубликованный ответ - я знаю это.
А как насчет небольшого поведения по умолчанию?
String.prototype.ditto = function() {
var c = Number( arguments[ 0 ] ) || 2,
r = this.valueOf();
while ( --c ) {
r += this;
}
return r;
}
"foo".ditto();
Потому что, хотя нерекурсивный метод будет обрабатывать произвольно большие повторы без выхода за пределы стека вызовов, он намного медленнее.
Отчасти для собственного развлечения, а отчасти для того, чтобы указать самым простым способом, я знаю, что есть много способов снять шкуру с кошки, и в зависимости от ситуации вполне возможно, что метод Лучший, очевидно, не идеален.
Относительно быстрый и сложный метод может привести к сбою и сгоранию при определенных обстоятельствах, в то время как более медленный и простой метод может со временем выполнить свою работу.
Некоторые методы могут быть не более чем эксплойтами и, как таковые, склонны к тому, что фиксированный не существует, а другие методы могут прекрасно работать в любых условиях, но построены так, что один просто не знает, как это работает.
«Так что, если я не знаю, как это работает ?!»
Серьезно?
JavaScript страдает одной из самых сильных сторон; он очень терпим к плохому поведению и настолько гибок, что может изгибаться назад, чтобы вернуть результаты, хотя для всех было бы лучше, если бы он щелкнул!
"С большой властью приходит большая ответственность" ;-)
Но что более серьезно и важно, хотя общие вопросы, подобные этому, действительно приводят к удивительным результатам в форме умный, он отвечает, что, как минимум, расширяет знания и кругозор, в конце концов, поставленную задачу - практический сценарий, который использует полученный метод - может потребоваться немного меньше или немного больше умный, чем предлагается.
Эти алгоритмы "идеально" забавны и все такое, но "один размер подходит всем" редко, если вообще когда-либо, будет лучше, чем сделанный на заказ.
Эта проповедь была доставлена вам из-за недостатка сна и преходящего интереса. Идите и пишите код!
Хорошие новости! String.prototype.repeat - это теперь часть JavaScript.
"yo".repeat(2);
// returns: "yoyo"
Этот метод поддерживается всеми основными браузерами, кроме Internet Explorer. Актуальный список см. В MDN: String.prototype.repeat> Совместимость с браузером.
В MDN есть полифилл для браузеров без поддержки.
Спасибо за отчет о текущем состоянии дел, хотя я думаю, что полифилл Mozilla слишком сложен для большинства нужд (я предполагаю, что они пытаются имитировать поведение своей эффективной реализации C), поэтому на самом деле они не отвечают требованию OP относительно краткости. Любой из других подходов, созданных как полифил, обязательно будет более лаконичным ;-)
Определенно! Но при использовании встроенного варианта обязательно должен быть самый лаконичный. Поскольку полифилы в основном представляют собой просто обратные порты, они могут быть немного сложными для обеспечения совместимости со спецификациями (или предлагаемыми спецификациями в данном случае). Я добавил его для полноты, полагаю, ОП решает, какой метод использовать.
Во-первых, вопросы OP, похоже, касаются краткости - что, как я понимаю, означает «простой и легкий для чтения», в то время как большинство ответов, похоже, касаются эффективности - что, очевидно, не одно и то же, и я также думаю, что если вы не реализуете какие-то очень конкретные алгоритмы обработки больших данных, не должны беспокоить вас, когда вы приступаете к реализации основных функций Javascript для манипулирования данными. Лаконичность гораздо важнее.
Во-вторых, как заметил Андре Ласло, String.repeat является частью ECMAScript 6 и уже доступен в нескольких популярных реализациях, поэтому самая краткая реализация String.repeat - это не реализовывать его ;-)
Наконец, если вам нужно поддерживать хосты, которые не предлагают реализацию ECMAScript 6, полифилл MDN, упомянутый Андре Ласло, совсем не лаконичен.
Итак, без лишних слов - вот мой полифилл лаконичный:
String.prototype.repeat = String.prototype.repeat || function(n){
return n<=1 ? this : this.concat(this.repeat(n-1));
}
Да, это рекурсия. Мне нравятся рекурсии - они простые и, если все сделано правильно, их легко понять. Что касается эффективности, если язык поддерживает ее, они могут быть очень эффективными, если написаны правильно.
Судя по моим тестам, этот метод примерно на 60% быстрее, чем подход Array.join. Хотя это, очевидно, нигде не идет вразрез с обезличенной реализацией, она намного проще, чем обе.
Моя тестовая установка - это узел v0.10, использующий «Строгий режим» (я думаю, что он включает своего рода ТШО), вызывающий repeat(1000) для 10-символьной строки миллион раз.
String.prototype.repeat теперь является стандартом ES6.
'abc'.repeat(3); //abcabcabc
красивый! .. но мне не подходит (не поддерживается на ios <9): kangax.github.io/compat-table/es6
@Benjamin Воспользуйтесь полифилом по ссылке.
Думаю, должен быть ответ приколот.
Используйте Array(N+1).join("string_to_repeat")
Мне это нравится. Идк, почему его там нет.
любить это. так просто и чисто
Используйте Lodash для служебных функций Javascript, таких как повторяющиеся строки.
Lodash обеспечивает хорошую производительность и совместимость с ECMAScript.
Я настоятельно рекомендую его для разработки пользовательского интерфейса, и он также хорошо работает на стороне сервера.
Вот как повторить строку «yo» 2 раза с помощью Lodash:
> _.repeat('yo', 2)
"yoyo"
Это примерно так же кратко, как и получается:
function repeat(s, n) { return new Array(n+1).join(s); }
Если вы также заботитесь о производительности, это гораздо лучший подход:
function repeat(s, n) { var a=[],i=0;for(;i<n;)a[i++]=s;return a.join(''); }
Если вы хотите сравнить производительность обоих вариантов, см. Тестовые тесты эта рабочий пример и эта рабочий пример. Во время моих собственных тестов второй вариант был примерно в 2 раза быстрее в Firefox и примерно в 4 раза быстрее в Chrome!
В современных браузерах теперь также можно сделать это:
function repeat(s,n) { return s.repeat(n) };
Этот вариант не только короче, чем оба других варианта, но и даже быстрее, чем второй вариант.
К сожалению, это не работает ни в одной версии Internet Explorer. Числа в таблице указывают первую версию браузера, полностью поддерживающую метод:
function repeat(pattern, count) {
for (var result = '';;) {
if (count & 1) {
result += pattern;
}
if (count >>= 1) {
pattern += pattern;
} else {
return result;
}
}
}
Вы можете проверить это на JSFiddle. По сравнению с взломанным Array.join, мой, грубо говоря, От 10 (Chrome) до 100 (Safari) до 200 (Firefox) раз быстрее (в зависимости от браузера).
Объединение строк на основе числа.
function concatStr(str, num) {
var arr = [];
//Construct an array
for (var i = 0; i < num; i++)
arr[i] = str;
//Join all elements
str = arr.join('');
return str;
}
console.info(concatStr("abc", 3));
Надеюсь, это поможет!
ES-Next есть много способовES2015 / ES6 был реализован этот метод repeat()!/**
* str: String
* count: Number
*/
const str = `hello repeat!\n`, count = 3;
let resultString = str.repeat(count);
console.info(`resultString = \n${resultString}`);
/*
resultString =
hello repeat!
hello repeat!
hello repeat!
*/
({ toString: () => 'abc', repeat: String.prototype.repeat }).repeat(2);
// 'abcabc' (repeat() is a generic method)
// Examples
'abc'.repeat(0); // ''
'abc'.repeat(1); // 'abc'
'abc'.repeat(2); // 'abcabc'
'abc'.repeat(3.5); // 'abcabcabc' (count will be converted to integer)
// 'abc'.repeat(1/0); // RangeError
// 'abc'.repeat(-1); // RangeErrorES2017 / ES8, новое добавление String.prototype.padStart()const str = 'abc ';
const times = 3;
const newStr = str.padStart(str.length * times, str.toUpperCase());
console.info(`newStr =`, newStr);
// "newStr = " "ABC ABC abc "ES2017 / ES8, новое добавление String.prototype.padEnd()const str = 'abc ';
const times = 3;
const newStr = str.padEnd(str.length * times, str.toUpperCase());
console.info(`newStr =`, newStr);
// "newStr = " "abc ABC ABC "http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.repeat
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/padStart
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
Еще одна функция повтора:
function repeat(s, n) {
var str = '';
for (var i = 0; i < n; i++) {
str += s;
}
return str;
}
С ES8 вы также можете использовать для этого padStart или padEnd. например.
var str = 'cat';
var num = 23;
var size = str.length * num;
"".padStart(size, str) // outputs: 'catcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcatcat'
Чтобы повторить строку заданное количество раз, мы можем использовать встроенный метод repeat() в JavaScript.
Вот пример, в котором следующая строка повторяется 4 раза:
const name = "king";
const repeat = name.repeat(4);
console.info(repeat);
Выход:
"kingkingkingking"
или мы можем создать нашу собственную версию функции repeat() следующим образом:
function repeat(str, n) {
if (!str || !n) {
return;
}
let final = "";
while (n) {
final += s;
n--;
}
return final;
}
console.info(repeat("king", 3))
(изначально размещено на https://reactgo.com/javascript-repeat-string/)
Более 10 лет назад у меня было хорошо известное решение этой проблемы, которое я использовал в качестве примера в статье по оптимизации JavaScript за пару месяцев до того, как вы задали этот вопрос: webreference.com/programming/javascript/jkm3/3.html Очевидно, большинство людей забыли об этом коде, и я не вижу ниже столь же хороших решений, как мое. Лучший алгоритм выглядит так, как будто он был взят из моего кода; за исключением неправильного понимания того, как работает мой код, он выполняет один дополнительный шаг экспоненциальной конкатенации, который исключается в моем оригинале с помощью специального цикла.