Powtórz znak N razy

602

W Perlu mogę powtórzyć znak wiele razy, używając składni:

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

Czy istnieje prosty sposób na osiągnięcie tego w JavaScript? Oczywiście mogę użyć funkcji, ale zastanawiałem się, czy istnieje jakieś wbudowane podejście lub inna sprytna technika.

Steve
źródło

Odpowiedzi:

1201

Obecnie repeatmetoda łańcuchowa jest implementowana prawie wszędzie. (Nie ma go w Internet Explorerze .) Więc jeśli nie potrzebujesz obsługi starszych przeglądarek, możesz po prostu napisać:

"a".repeat(10)

Wcześniej repeatkorzystaliśmy z tego hacka:

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

(Zauważ, że tablica o długości 11 daje ci tylko 10 „a”, ponieważ Array.joinumieszcza argument między elementami tablicy.)

Simon wskazuje również, że zgodnie z tym jsperfem wydaje się, że w Safari i Chrome (ale nie Firefox) jest szybsze wielokrotne powtarzanie postaci po prostu przez dodanie pętli for (choć nieco mniej zwięzłe).

Jason Orendorff
źródło
4
Dodatkowo możesz użyć zmiennej zamiast stałej długości - Array (20-len), powiedzmy, aby uzupełnić ciąg do 20.
John C
7
Metoda pętli może być szybsza, ale bardziej szczegółowa. Poza tym zastanawiają mnie wszystkie głosy poparcia dla pierwszego komentarza, biorąc pod uwagę, że gdy będzie to ogólnie przydatne, gdy długość tablicy jest zmienna, np.Array(rawValue.length + 1).join("*")
Dexygen 30.01.2015
Nie działa to w przypadku 0 i 1, ponieważ dają identyczne wyniki.
Ryan
2
Wzór jest następujący Array(n+1).join("a"). Gdy n = 0, zwraca pusty ciąg, a gdy n = 1, zwraca "a". Myślę, że to działa we wszystkich przypadkach.
Jason Orendorff,
1
@Neel To dlatego, że silniki JS nakładają ograniczenie długości łańcucha. W Chrome i Firefox limit ten wynosi blisko 2 ^ 30 (około miliarda). 10 ^ 12 to jeden bilion.
Jason Orendorff,
301

W nowej harmonii ES6 będziesz miał rodzimy sposób na powtarzanie tego . Również ES6 teraz tylko eksperymentalny, ta funkcja jest już dostępna w Edge, FF, Chrome i Safari

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

I na pewno, jeśli funkcja powtarzania nie jest dostępna, możesz użyć starego dobra Array(n + 1).join("abc")

Salvador Dali
źródło
54

Wygodne, jeśli często się powtarzasz:

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)  )

Kennebec
źródło
53
Złą praktyką kodowania jest zanieczyszczanie wbudowanych prototypów.
tuomassalo
3
@nurettin patrz programmers.stackexchange.com/questions/104320/... po więcej dyskusji. Dodałbym (odpowiednio skalowaną) funkcję statycznego pomocnika, z podpisem repeat(str, n).
tuomassalo
4
Chciałbym usunąć n= n || 1część (lub sprawdzić, czy njest niezdefiniowana), abyś mógł również powtarzać 0czasy.
chodorowicz
3
Zobacz także oficjalną polifill Mozilli dla ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland
3
@ChrisV, String.repeatzostał dodany tylko w ES6, który został sfinalizowany dopiero w czerwcu 2015 r. Myślę więc, że mój punkt widzenia był ważny, kiedy napisałem go w 2012 r. :)
tuomassalo
13

Najbardziej efektywnym sposobem na obniżenie wydajności jest https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

Krótka wersja jest poniżej.

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

Polyfill z Mozilli:

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;
  }
}
Konstantin Victorov
źródło
To jest dobre, ale nowe natywne „powtarzanie” jest jeszcze szybsze i nie wymaga implementacji, i tak dzięki!
Goty Metal
1
możesz rozwinąć znaczenie count >>>= 1, pattern += pattern;? jakie to stwierdzenie?
Tsahi Asher,
Więc to jest polifill dla natywnego powtórzenia? Po prostu dodaj if (!String.prototype.repeat) {na początku i }na końcu.
trlkly
>>> = jest niepodpisany prawy shift shift (jak w count = count >>> 1) patrz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004
12

Alternatywą jest:

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

Jeśli chcesz powtórzyć wiele znaków, pomnóż warunek:

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

UWAGA: Nie musisz przekraczać 1, jak w przypadkuword = Array(11).join('a')

cukierek
źródło
10

Jeśli nie masz nic przeciwko włączeniu biblioteki do swojego projektu, lodash ma funkcję powtarzania.

_.repeat('*', 3);
// → '***

https://lodash.com/docs#repeat

Nathan Danger
źródło
10

Dla wszystkich przeglądarek

Poniższa funkcja będzie działać znacznie szybciej niż opcja sugerowana w zaakceptowanej odpowiedzi:

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

Użyłbyś tego w ten sposób:

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

Aby porównać wydajność tej funkcji z wydajnością opcji zaproponowanej w zaakceptowanej odpowiedzi, zobacz ten Fiddle i ten Fiddle dla testów porównawczych.

Tylko dla współczesnych przeglądarek

W nowoczesnych przeglądarkach możesz teraz to zrobić za pomocą String.prototype.repeatmetody:

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

Przeczytaj więcej o tej metodzie na MDN .

Ta opcja jest jeszcze szybsza. Niestety nie działa w żadnej wersji Internet Explorera. Liczby w tabeli określają pierwszą wersję przeglądarki, która w pełni obsługuje tę metodę:

wprowadź opis zdjęcia tutaj

John Slegers
źródło
9
Array(10).fill('a').join('')

Chociaż najczęściej głosowana odpowiedź jest nieco bardziej zwarta, dzięki takiemu podejściu nie musisz dodawać dodatkowego elementu tablicy.

Grzegorz Pawlik
źródło
1
Niestety metoda wypełniania nie jest obsługiwana w IE, a jeśli nie jesteś zgodny z IE, możesz równie dobrze użyć metody powtarzania.
Michiel
1
Dlaczego miałbyś skorzystać z dodatkowej metody, fill()jeśli zrobiłbyś to samo z join("a")samym ...
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"
);
yckart
źródło
7

W ES2015 / ES6 możesz używać "*".repeat(n)

Po prostu dodaj to do swoich projektów i gotowe.

  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()) 
    };
webdeb
źródło
SCRIPT5029: Długość tablicy musi być skończoną dodatnią liczbą całkowitą, gdy próbujesz użyć tego podejścia
andrepaulo
5

Innym ciekawym sposobem na szybkie powtórzenie n znaku jest użycie pomysłu z algorytmu szybkiego potęgowania:

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;
};
csharpfolk
źródło
Dlaczego mówisz „ciekawy sposób”? co jest tu tak interesującego? to oczywiste rozwiązanie, najbardziej podstawowy podstawowy przykład programu komputerowego.
vsync,
2

Do powtórzenia wartości w moich projektach używam powtarzania

Na przykład:

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

ale bądź ostrożny, ponieważ ta metoda została dodana do specyfikacji ECMAScript 6.

Ezequiel García
źródło
2
function repeatString(n, string) {
  var repeat = [];
  repeat.length = n + 1;
  return repeat.join(string);
}

repeatString(3,'x'); // => xxx
repeatString(10,'🌹'); // => "🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹"
alejandro
źródło
1

Oto czego używam:

function repeat(str, num) {
        var holder = [];
        for(var i=0; i<num; i++) {
            holder.push(str);
        }
        return holder.join('');
    }
Koushik Das
źródło
0

Mam zamiar rozwinąć odpowiedź @ bonbon . Jego metoda jest łatwym sposobem „dołączenia N znaków do istniejącego łańcucha”, na wypadek, gdyby ktoś musiał to zrobić. Na przykład, ponieważ „google” to 1, po którym następuje 100 zer .

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>

UWAGA: Musisz dodać długość warunku oryginalnego do warunkowego.

Bruno Bronosky
źródło
0

Lodash oferuje podobną funkcjonalność jak funkcja Javascript repeat (), która nie jest dostępna we wszystkich przeglądarkach. Nazywa się _.repeat i jest dostępny od wersji 3.0.0:

_.repeat('a', 10);
0x4a6f4672
źródło
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);
Brud
źródło
0

Może być również stosowany jako jedna linijka:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}
Sarsaparilla
źródło
W każdym konkursie „za” jest szybsze niż „podczas”. :-)
czerwca
0

W CoffeeScript:

( 'a' for dot in [0..10]).join('')
David Mendez
źródło
0

w ten sposób można wywołać funkcję i uzyskać wynik za pomocą Array () i join ()

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

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

Amir Danish
źródło
-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"
Caglayan ALTINCI
źródło
1
Zastępuje String.prototype.repeatto natywnie zawarte w obecnych przeglądarkach. Ponadto, dlaczego to zminimalizować? Nie musisz pisać wszystkiego w jednym wierszu.
Blender
Brak funkcji powtarzania w IE, dlatego wymagany jest prototyp.
Caglayan ALTINCI
-3

Oto wersja ES6

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

Maxali
źródło