Répéter le caractère N fois

602

En Perl, je peux répéter plusieurs fois un caractère en utilisant la syntaxe:

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

Existe-t-il un moyen simple d'accomplir cela en Javascript? Je peux évidemment utiliser une fonction, mais je me demandais s'il y avait une approche intégrée ou une autre technique intelligente.

Steve
la source

Réponses:

1201

De nos jours, la repeatméthode des chaînes est implémentée presque partout. (Ce n'est pas dans Internet Explorer .) Donc, sauf si vous devez prendre en charge des navigateurs plus anciens, vous pouvez simplement écrire:

"a".repeat(10)

Avant repeat, nous utilisions ce hack:

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

(Notez qu'un tableau de longueur 11 ne vous donne que 10 "a", car Array.joinplace l'argument entre les éléments du tableau.)

Simon souligne également que selon ce jsperf , il semble qu'il soit plus rapide dans Safari et Chrome (mais pas Firefox) de répéter plusieurs fois un caractère en ajoutant simplement en utilisant une boucle for (bien qu'un peu moins concise).

Jason Orendorff
la source
4
De plus, vous pouvez utiliser une variable au lieu d'une longueur fixe - Array (20-len), disons pour remplir une chaîne jusqu'à 20.
John C
7
La méthode de boucle peut être plus rapide mais plus prolixe. De plus, je suis déconcerté par toutes les votes positifs pour le premier commentaire, étant donné que lorsque cela sera généralement utile lorsque la longueur du tableau est variable, par exempleArray(rawValue.length + 1).join("*")
Dexygen
Cela ne fonctionne pas dans le cas 0 et 1, car ils produisent des résultats identiques.
Ryan
2
La formule est Array(n+1).join("a"). Lorsque n = 0, cela renvoie la chaîne vide, et lorsque n = 1, il renvoie "a". Je pense donc que cela fonctionne dans tous les cas.
Jason Orendorff
1
@Neel C'est parce que les moteurs JS imposent une limite sur la longueur des chaînes. Dans Chrome et Firefox, la limite est proche de 2 ^ 30 (environ un milliard). 10 ^ 12 est un billion.
Jason Orendorff
301

Dans une nouvelle harmonie ES6, vous aurez une manière native de le faire avec la répétition . Également ES6 en ce moment uniquement expérimental, cette fonctionnalité est déjà disponible dans Edge, FF, Chrome et Safari

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

Et sûrement si la fonction de répétition n'est pas disponible, vous pouvez utiliser old-good Array(n + 1).join("abc")

Salvador Dali
la source
54

Pratique si vous vous répétez beaucoup:

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
la source
53
C'est une mauvaise pratique de codage de polluer les prototypes de buildins.
tuomassalo
3
@nurettin voir programmers.stackexchange.com/questions/104320/… pour plus de discussion. J'ajouterais une fonction d'assistance statique (délimitée correctement), avec une signature de repeat(str, n).
tuomassalo
4
Je supprimerais la n= n || 1pièce (ou vérifierais si elle nn'est pas définie), vous pouvez donc également répéter les 0temps
chodorowicz
3
Jetez également un œil au polyfill officiel de Mozilla pour ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland
3
@ChrisV, a String.repeatété ajouté uniquement dans ES6, qui n'a été finalisé qu'en juin 2015. Je pense donc que mon argument était valable lorsque je l'ai écrit en 2012. :)
tuomassalo
13

La manière la plus performante est https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

La version courte est ci-dessous.

  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 de 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;
  }
}
Konstantin Victorov
la source
C'est une bonne chose, mais la nouvelle "répétition" native est encore plus rapide et ne nécessite aucune implémentation, merci quand même!
Goty Metal
1
pouvez-vous expliquer le sens de count >>>= 1, pattern += pattern;? quel genre de déclaration est-ce?
Tsahi Asher
C'est donc un polyfill pour la répétition native, alors? Ajoutez simplement un if (!String.prototype.repeat) {au début et }à la fin.
trlkly
>>> = est une affectation de décalage vers la droite non signée (comme dans count = count >>> 1) voir: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004
12

Une alternative est:

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

Si vous devez répéter plusieurs caractères, multipliez votre conditionnel:

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

REMARQUE: vous n'avez pas besoin de dépasser de 1 comme avecword = Array(11).join('a')

bonbon
la source
10

Si vous n'êtes pas opposé à l'inclusion d'une bibliothèque dans votre projet, lodash a une fonction de répétition.

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

https://lodash.com/docs#repeat

Nathan Danger
la source
10

Pour tous les navigateurs

La fonction suivante fonctionnera beaucoup plus rapidement que l'option suggérée dans la réponse acceptée:

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

Vous l'utiliseriez comme ceci:

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

Pour comparer les performances de cette fonction avec celles de l'option proposée dans la réponse acceptée, voir ce violon et ce violon pour les repères.

Pour les navigateurs modernes uniquement

Dans les navigateurs modernes, vous pouvez désormais le faire en utilisant la String.prototype.repeatméthode:

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

En savoir plus sur cette méthode sur MDN .

Cette option est encore plus rapide. Malheureusement, cela ne fonctionne dans aucune version d'Internet Explorer. Les chiffres du tableau spécifient la première version du navigateur qui prend entièrement en charge la méthode:

entrez la description de l'image ici

John Slegers
la source
9
Array(10).fill('a').join('')

Bien que la réponse la plus votée soit un peu plus compacte, avec cette approche, vous n'avez pas besoin d'ajouter un élément de tableau supplémentaire.

Grzegorz Pawlik
la source
1
Malheureusement, la méthode fill n'est pas prise en charge dans IE, et si vous n'êtes pas compatible IE, vous pouvez tout aussi bien utiliser la méthode repeat.
Michiel
1
Pourquoi utiliseriez-vous la méthode supplémentaire fill()si vous faites de même avec join("a")seul ...
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
la source
7

Dans ES2015 / ES6, vous pouvez utiliser "*".repeat(n)

Ajoutez donc ceci à vos projets, et vous êtes prêt à partir.

  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
la source
SCRIPT5029: La longueur du tableau doit être un entier positif fini lorsque vous essayez d'utiliser cette approche
andrepaulo
5

Une autre façon intéressante de répéter rapidement le caractère n est d'utiliser l'idée de l'algorithme d'exponentiation rapide:

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
la source
Pourquoi dites-vous "façon intéressante"? qu'est-ce qui est si intéressant ici? c'est la solution incontournable, l'exemple fondamental le plus élémentaire d'un programme informatique.
vsync
2

Pour répéter une valeur dans mes projets j'utilise répéter

Par exemple:

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

mais soyez prudent car cette méthode a été ajoutée à la spécification ECMAScript 6.

Ezequiel García
la source
2
function repeatString(n, string) {
  var repeat = [];
  repeat.length = n + 1;
  return repeat.join(string);
}

repeatString(3,'x'); // => xxx
repeatString(10,'🌹'); // => "🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹"
alejandro
la source
1

Voici ce que j'utilise:

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

Je vais développer la réponse de @ bonbon . Sa méthode est un moyen simple "d'ajouter N caractères à une chaîne existante", juste au cas où quelqu'un aurait besoin de le faire. Par exemple, car "un google" est un 1 suivi de 100 zéros .

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>

REMARQUE: vous devez ajouter la longueur de la chaîne d'origine au conditionnel.

Bruno Bronosky
la source
0

Lodash offre une fonctionnalité similaire à la fonction Javascript repeat () qui n'est pas disponible dans tous les navigateurs. Il s'appelle _.repeat et est disponible depuis la version 3.0.0:

_.repeat('a', 10);
0x4a6f4672
la source
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);
Saleté
la source
0

Peut également être utilisé comme doublure:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}
Salsepareille
la source
Sur n'importe quel concours, "pour" est plus rapide que "pendant". :-)
junihh
0

Dans CoffeeScript:

( 'a' for dot in [0..10]).join('')
David Mendez
la source
0

c'est ainsi que vous pouvez appeler une fonction et obtenir le résultat à l'aide de Array () et join ()

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

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

Amir Danois
la source
-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
la source
1
Cela remplace ce String.prototype.repeatqui est nativement inclus dans les navigateurs actuels. Aussi, pourquoi le minimiser? Vous n'avez pas besoin de tout écrire sur une seule ligne.
Blender
Aucune fonctionnalité de «répétition» dans IE, donc prototype requis.
Caglayan ALTINCI
-3

Voici une version ES6

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

Maxali
la source