Повторіть символ N разів


602

У Perl я можу повторити символ кілька разів, використовуючи синтаксис:

$a = "a" x 10; // results in "aaaaaaaaaa"

Чи є простий спосіб досягти цього в Javascript? Я, очевидно, можу використовувати функцію, але мені було цікаво, чи є якийсь вбудований підхід чи якась інша розумна техніка.

Відповіді:


1201

У ці дні repeatструнний метод реалізується майже скрізь. (Це не в Internet Explorer .) Отже, якщо вам не потрібно підтримувати старіші веб-переглядачі, ви можете просто написати:

"a".repeat(10)

Раніше repeatми використовували цей злом:

Array(11).join("a") // create string with 10 a's: "aaaaaaaaaa"

(Зверніть увагу, що масив довжиною 11 отримує у вас лише 10 "a" s, оскільки Array.joinставить аргумент між елементами масиву.)

Саймон також вказує, що згідно з цим jsperf , здається, що в Safari та Chrome (але не в Firefox) швидше повторити символ кілька разів, просто додавши його за допомогою циклу (хоча трохи менш стисло).


4
Крім того, ви можете використовувати змінну замість фіксованої довжини - Array (20-len), скажімо, накладення рядка до 20.
Джон C

7
Метод циклу може бути швидшим, але його більш багатослівним. Плюс мене спантеличують всі відгуки за перший коментар, враховуючи, що коли це, як правило, стане в нагоді, коли довжина масиву мінлива, наприкладArray(rawValue.length + 1).join("*")
Dexygen

Це не працює у випадку 0 та 1, оскільки вони дають однакові результати.
Райан

2
Формула така Array(n+1).join("a"). Коли n = 0, це повертає порожній рядок, а коли n = 1, він повертається "a". Тому я думаю, що це працює у всіх випадках.
Джейсон Орендорф

1
@Neel Це тому, що двигуни JS встановлюють обмеження на довжину рядка. У Chrome і Firefox ліміт становить близько 2 ^ 30 (близько мільярда). 10 ^ 12 - це один трильйон.
Джейсон Орендорф

301

У новій гармонії ES6 у вас буде рідний спосіб зробити це повтором . Крім того, ES6 зараз лише експериментальний, ця функція вже доступна в Edge, FF, Chrome та Safari

"abc".repeat(3) // "abcabcabc"

І звичайно, якщо функція повторення відсутня, ви можете використовувати старий-добрий Array(n + 1).join("abc")


54

Зручно, якщо ви багато повторюєте:

String.prototype.repeat = String.prototype.repeat || function(n){
  n= n || 1;
  return Array(n+1).join(this);
}

alert(  'Are we there yet?\nNo.\n'.repeat(10)  )


53
Погана практика кодування забруднювати прототипи вбудованих.
tuomassalo

3
@nurettin див. програмісти.stackexchange.com/ questions/104320/… для більшого обговорення. Я б додав (правильно встановлену область) статичну функцію помічника, з підписом repeat(str, n).
tuomassalo

4
Я б видалив n= n || 1деталь (або перевірте, чи nне визначено), тому ви також можете повторити 0рази.
chodorowicz

3
Також перегляньте офіційну поліграфічну заправку Mozilla для ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ерік Біркеланд

3
@ChrisV, String.repeatдодано лише в ES6, який не було доопрацьовано до червня 2015 року. Тому я думаю, що мій пункт був дійсним, коли я написав це у 2012 році. :)
tuomassalo

13

Найбільш ефективний спосіб роботи - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

Коротка версія наведена нижче.

  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;
  };
  var a = "a";
  console.debug(a.repeat(10));

Поліфосфат від Mozilla:

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;
  }
}

Це добре, але нове "повторення" ще швидше і не потребує впровадження, все-таки спасибі!
Goty Metal

1
чи можете ви детальніше розповісти про значення count >>>= 1, pattern += pattern;? що це за твердження?
Цахі Ашер

Так це поліфіл для рідного повторення, тоді? Просто додайте if (!String.prototype.repeat) {початок і }кінець.
trlkly

>>> = це вправо без знака присвоювання зсуву (як при підрахунку кількості = >>> 1) см: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / ...
user1441004

12

Альтернатива:

for(var word = ''; word.length < 10; word += 'a'){}

Якщо вам потрібно повторити кілька знаків, помножте свої умовні:

for(var word = ''; word.length < 10 * 3; word += 'foo'){}

ПРИМІТКА. Не потрібно перевертати на 1, як приword = Array(11).join('a')



10

Для всіх браузерів

Наступна функція буде виконуватись набагато швидше, ніж параметр, запропонований у прийнятій відповіді:

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

Ви використовуєте його так:

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

Для порівняння продуктивності цієї функції з варіантом, запропонованим у прийнятій відповіді, див. Цей Fiddle та цей Fiddle для орієнтирів.

Тільки для модернізованих браузерів

У сучасних браузерах зараз це можна зробити String.prototype.repeatметодом:

var repeatedString = "a".repeat(10);

Детальніше про цей метод читайте на MDN .

Цей варіант ще швидший. На жаль, він не працює в будь-якій версії Internet Explorer. Цифри в таблиці вказують першу версію браузера, яка повністю підтримує метод:

введіть тут опис зображення


9
Array(10).fill('a').join('')

Хоча відповідь, яка найбільше голосує, трохи компактніша, при такому підході вам не доведеться додавати додатковий елемент масиву.


1
На жаль, метод IE не підтримується в IE, і якщо ви не IE сумісний, ви можете також добре використовувати метод повтору.
Міхель

1
Чому б ви використовували додатковий метод, fill()якщо ви робите те саме з join("a")самотнім ...
vsync,

7
/**  
 * Repeat a string `n`-times (recursive)
 * @param {String} s - The string you want to repeat.
 * @param {Number} n - The times to repeat the string.
 * @param {String} d - A delimiter between each string.
 */

var repeat = function (s, n, d) {
    return --n ? s + (d || "") + repeat(s, n, d) : "" + s;
};

var foo = "foo";
console.log(
    "%s\n%s\n%s\n%s",

    repeat(foo),        // "foo"
    repeat(foo, 2),     // "foofoo"
    repeat(foo, "2"),   // "foofoo"
    repeat(foo, 2, "-") // "foo-foo"
);

7

У ES2015 / ES6 ви можете використовувати "*".repeat(n)

Тож просто додайте це до своїх проектів, і ви корисні.

  String.prototype.repeat = String.prototype.repeat || 
    function(n) {
      if (n < 0) throw new RangeError("invalid count value");
      if (n == 0) return "";
      return new Array(n + 1).join(this.toString()) 
    };

SCRIPT5029: При спробі використання цього підходу довжина масиву повинна бути кінцевим додатним цілим числом
andrepaulo

5

Ще один цікавий спосіб швидкого повторення n символів - це використання ідеї з алгоритму швидкої експоненції:

var repeatString = function(string, n) {
    var result = '', i;

    for (i = 1; i <= n; i *= 2) {
        if ((n & i) === i) {
            result += string;
        }
        string = string + string;
    }

    return result;
};

Чому ви говорите "цікавий шлях"? що тут такого цікавого? це очевидне рішення, найпростіший фундаментальний приклад комп'ютерної програми.
vsync

2

Для повторення значення в моїх проектах я використовую повтор

Наприклад:

var n = 6;
for (i = 0; i < n; i++) {
    console.log("#".repeat(i+1))
}

але будьте обережні, оскільки цей метод додано до специфікації ECMAScript 6.


2
function repeatString(n, string) {
  var repeat = [];
  repeat.length = n + 1;
  return repeat.join(string);
}

repeatString(3,'x'); // => xxx
repeatString(10,'🌹'); // => "🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹"

1

Ось що я використовую:

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

0

Я збираюся розкрити відповідь на @ bonbon . Його метод - це простий спосіб "додати N символів до існуючого рядка", на всякий випадок, якщо комусь потрібно це зробити. Наприклад, оскільки "google" - це 1, що супроводжується 100 нулями .

for(var google = '1'; google.length < 1 + 100; google += '0'){}
document.getElementById('el').innerText = google;
<div>This is "a google":</div>
<div id="el"></div>

ПРИМІТКА. Довжину початкового рядка потрібно додати до умовної.



0
var stringRepeat = function(string, val) {
  var newString = [];
    for(var i = 0; i < val; i++) {
      newString.push(string);
  }
  return newString.join('');
}

var repeatedString = stringRepeat("a", 1);

0

Також може використовуватися як одноколісний:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}

На будь-якому змаганні "за" швидше, ніж "поки". :-)
1717


0

ось як можна викликати функцію та отримати результат за допомогою Array () та join ()

function repeatStringNumTimes(str, num) {
  // repeat after me
  return num > 0 ? Array(num+1).join(str) : "";
}

console.log(repeatStringNumTimes("a",10))


-1
String.prototype.repeat = function (n) { n = Math.abs(n) || 1; return Array(n + 1).join(this || ''); };

// console.log("0".repeat(3) , "0".repeat(-3))
// return: "000" "000"

1
Це перезаписи, String.prototype.repeatякі в основному містяться в поточних браузерах. Крім того, навіщо його мінімізувати? Не потрібно писати все це одним рядком.
Блендер

У IE немає функції "повтору", тому прототип вимагається.
Каглаян ALTINCI

-3

Ось версія ES6

const repeat = (a,n) => Array(n).join(a+"|$|").split("|$|");
repeat("A",20).forEach((a,b) => console.log(a,b+1))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.