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.

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


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


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


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

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



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


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.


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

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

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

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.


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

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

1

Oto czego używam:

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

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.



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

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

W każdym konkursie „za” jest szybsze niż „podczas”. :-)
czerwca


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


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.