Ripeti il ​​personaggio N volte


602

In Perl posso ripetere più volte un personaggio usando la sintassi:

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

C'è un modo semplice per ottenere questo risultato in Javascript? Ovviamente posso usare una funzione, ma mi chiedevo se ci fosse un approccio integrato o qualche altra tecnica intelligente.

Risposte:


1201

In questi giorni, il repeatmetodo stringa è implementato quasi ovunque. (Non è in Internet Explorer .) Quindi, a meno che non sia necessario supportare browser meno recenti, è possibile semplicemente scrivere:

"a".repeat(10)

Prima repeat, abbiamo usato questo trucco:

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

(Nota che un array di lunghezza 11 ti dà solo 10 "a" s, poiché Array.joinmette l'argomento tra gli elementi dell'array.)

Simon sottolinea anche che secondo questo jsperf , sembra che sia più veloce in Safari e Chrome (ma non Firefox) ripetere un personaggio più volte semplicemente aggiungendo un ciclo for (anche se un po 'meno conciso).


4
Inoltre, puoi usare una variabile invece di una lunghezza fissa - Array (20-len), diciamo per riempire una stringa fino a 20.
John C

7
Il metodo loop può essere più veloce ma è più dettagliato. Inoltre sono perplesso da tutti i voti positivi per il primo commento, considerando che quando questo sarà generalmente utile quando la lunghezza della matrice è variabile, ad esempioArray(rawValue.length + 1).join("*")
Dexygen

Questo non funziona nel caso 0 e 1, poiché producono risultati identici.
Ryan,

2
La formula è Array(n+1).join("a"). Quando n = 0, restituisce la stringa vuota e quando n = 1, restituisce "a". Quindi penso che funzioni in tutti i casi.
Jason Orendorff il

1
@Neel Questo perché i motori JS impongono un limite alla lunghezza della stringa. In Chrome e Firefox, il limite è vicino a 2 ^ 30 (circa un miliardo). 10 ^ 12 è un trilione.
Jason Orendorff,

301

In una nuova armonia ES6, avrai un modo nativo per farlo ripetendo . Anche ES6 in questo momento solo sperimentale, questa funzione è già disponibile in Edge, FF, Chrome e Safari

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

E sicuramente se la funzione di ripetizione non è disponibile, puoi usare old-good Array(n + 1).join("abc")


54

Conveniente se ti ripeti molto:

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
È una cattiva pratica di codifica inquinare i prototipi dei builtin.
tuomassalo,

3
@nurettin vedi programmers.stackexchange.com/questions/104320/… per ulteriori discussioni. Aggiungerei una funzione di supporto statica (correttamente definita), con una firma di repeat(str, n).
tuomassalo,

4
Rimuoverei la n= n || 1parte (o verificherei se nnon è definita), quindi puoi anche ripetere i 0tempi.
Chodorowicz,

3
Dai un'occhiata anche al polyfill ufficiale di Mozilla per ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland l'

3
@ChrisV, è String.repeatstato aggiunto solo in ES6, che non è stato finalizzato fino a giugno 2015. Quindi penso che il mio punto fosse valido quando l'ho scritto nel 2012. :)
tuomassalo,

13

Il modo più performante è https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

La versione breve è sotto.

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

Questo è buono, ma la nuova "ripetizione" nativa è ancora più veloce e non ha bisogno di implementazione, grazie comunque!
Goty Metal,

1
puoi approfondire il significato di count >>>= 1, pattern += pattern;? che tipo di affermazione è?
Tsahi Asher,

Quindi questo è un polyfill per la ripetizione nativa, allora? Basta aggiungere un if (!String.prototype.repeat) {all'inizio e }alla fine.
trlkly

>>> = è assegnazione di turno a destra senza segno (come in count = count >>> 1) vedi: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004

12

Un'alternativa è:

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

Se devi ripetere più caratteri, moltiplica il tuo condizionale:

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

NOTA: non è necessario eseguire il superamento di 1 come perword = Array(11).join('a')



10

Per tutti i browser

La seguente funzione sarà molto più veloce dell'opzione suggerita nella risposta accettata:

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

Lo useresti così:

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

Per confrontare le prestazioni di questa funzione con quelle dell'opzione proposta nella risposta accettata, vedere questo Fiddle e questo Fiddle per i benchmark.

Solo per browser moderni

Nei browser moderni, ora puoi farlo utilizzando il String.prototype.repeatmetodo:

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

Ulteriori informazioni su questo metodo su MDN .

Questa opzione è ancora più veloce. Sfortunatamente, non funziona in nessuna versione di Internet Explorer. I numeri nella tabella specificano la prima versione del browser che supporta completamente il metodo:

inserisci qui la descrizione dell'immagine


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

Sebbene la risposta più votata sia un po 'più compatta, con questo approccio non è necessario aggiungere un ulteriore elemento dell'array.


1
Sfortunatamente, il metodo di riempimento non è supportato in IE e se non sei compatibile con IE puoi anche usare il metodo di ripetizione.
Michiel,

1
Perché dovresti usare il metodo extra fill()se fai lo stesso con join("a")solo ...
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

In ES2015 / ES6 è possibile utilizzare "*".repeat(n)

Quindi aggiungi questo ai tuoi progetti e sei pronto per partire.

  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: La lunghezza della matrice deve essere un numero intero positivo finito quando si tenta di utilizzare questo approccio
andrepaulo

5

Un altro modo interessante per ripetere rapidamente n carattere è usare l'idea dall'algoritmo di esponenziazione rapida:

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

Perché dici "modo interessante"? cosa c'è di così interessante qui? è la soluzione ovvia, l'esempio fondamentale di base di un programma per computer.
vsync,

2

Per ripetere un valore nei miei progetti, utilizzo repeat

Per esempio:

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

ma fai attenzione perché questo metodo è stato aggiunto alla specifica ECMAScript 6.


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

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

1

Ecco cosa uso:

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

0

Espanderò la risposta di @ bonbon . Il suo metodo è un modo semplice per "aggiungere N caratteri a una stringa esistente", nel caso in cui qualcuno debba farlo. Ad esempio, poiché "un google" è un 1 seguito da 100 zeri .

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>

NOTA: è necessario aggiungere la lunghezza della stringa originale al condizionale.



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

Può essere usato anche come un liner:

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

In qualsiasi concorso "per" è più veloce di "while". :-)
junihh


0

questo è il modo in cui è possibile chiamare una funzione e ottenere il risultato con l'aiuto di Array () e 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
Questo sovrascrive String.prototype.repeatche è incluso nativamente negli attuali browser. Inoltre, perché minimizzarlo? Non è necessario scrivere tutto in una riga.
Blender

Nessuna funzionalità di "ripetizione" in IE, quindi è necessario il prototipo.
Caglayan ALTINCI,

-3

Ecco una versione ES6

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.