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.

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


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


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


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

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



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


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.


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

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

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

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.


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

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

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

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.



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

Peut également être utilisé comme doublure:

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

Sur n'importe quel concours, "pour" est plus rapide que "pendant". :-)
junihh


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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.