Repetir personaje N veces

602

En Perl puedo repetir un personaje varias veces usando la sintaxis:

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

¿Hay una manera simple de lograr esto en Javascript? Obviamente puedo usar una función, pero me preguntaba si había algún enfoque integrado, o alguna otra técnica inteligente.

Steve
fuente

Respuestas:

1201

En estos días, el repeatmétodo de cadena se implementa en casi todas partes. (No está en Internet Explorer ). Entonces, a menos que necesite admitir navegadores más antiguos, simplemente puede escribir:

"a".repeat(10)

Antes repeat, usamos este truco:

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

(Tenga en cuenta que una matriz de longitud 11 solo obtiene 10 "a" s, ya que Array.joincoloca el argumento entre los elementos de la matriz).

Simon también señala que de acuerdo con este jsperf , parece que es más rápido en Safari y Chrome (pero no en Firefox) repetir un personaje varias veces simplemente agregando usando un bucle for (aunque un poco menos conciso).

Jason Orendorff
fuente
44
Además, puede usar una variable en lugar de una longitud fija: matriz (20 len), digamos para rellenar una cadena de hasta 20.
John C
77
El método de bucle puede ser más rápido pero es más detallado. Además, estoy sorprendido por todos los votos a favor del primer comentario, teniendo en cuenta que cuando esto generalmente será útil cuando la longitud de la matriz es variable, por ejemploArray(rawValue.length + 1).join("*")
Dexygen
Esto no funciona en el caso 0 y 1, ya que producen resultados idénticos.
Ryan
2
La formula es Array(n+1).join("a"). Cuando n = 0, esto devuelve la cadena vacía, y cuando n = 1, devuelve "a". Entonces creo que funciona en todos los casos.
Jason Orendorff
1
@Neel Eso se debe a que los motores JS imponen un límite en la longitud de la cadena. En Chrome y Firefox, el límite está cerca de 2 ^ 30 (alrededor de mil millones). 10 ^ 12 es un billón.
Jason Orendorff
301

En una nueva armonía ES6, tendrá una forma nativa de hacer esto con la repetición . También ES6 ahora solo experimental, esta característica ya está disponible en Edge, FF, Chrome y Safari

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

Y seguramente si la función de repetición no está disponible, puede usar old-good Array(n + 1).join("abc")

Salvador Dalí
fuente
54

Conveniente si te repites mucho:

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
fuente
53
Es una mala práctica de codificación contaminar los prototipos incorporados.
tuomassalo
3
@nurettin ver programmers.stackexchange.com/questions/104320/… para más discusión. Agregaría una función auxiliar estática (con un alcance adecuado), con una firma de repeat(str, n).
tuomassalo
44
Quitaría la n= n || 1parte (o comprobaría si nno está definida), para que también pueda repetir los 0tiempos.
chodorowicz
3
También eche un vistazo al polyfill oficial de Mozilla para ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland
3
@ChrisV, String.repeatsolo se agregó en ES6, que no se finalizó hasta junio de 2015. Así que creo que mi punto era válido cuando lo escribí en 2012. :)
tuomassalo
13

La forma más inteligente de rendimiento es https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

La versión corta está abajo.

  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
fuente
Esta es buena, pero la nueva "repetición" nativa es aún más rápida y no necesita implementación, ¡gracias de todos modos!
Goty Metal el
1
¿Puedes explicar el significado de count >>>= 1, pattern += pattern;? ¿Qué tipo de declaración es?
Tsahi Asher
Entonces, ¿este es un polyfill para la repetición nativa? Simplemente agregue un if (!String.prototype.repeat) {al principio y }al final.
Trly
>>> = es una asignación de desplazamiento a la derecha sin firmar (como en count = count >>> 1) ver: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004
12

Una alternativa es:

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

Si necesita repetir varios caracteres, multiplique su condicional:

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

NOTA: No tiene que sobrepasar en 1 como conword = Array(11).join('a')

caramelo
fuente
10

Si no se opone a incluir una biblioteca en su proyecto, lodash tiene una función de repetición.

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

https://lodash.com/docs#repeat

Nathan Danger
fuente
10

Para todos los navegadores

La siguiente función funcionará mucho más rápido que la opción sugerida en la respuesta aceptada:

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

Lo usarías así:

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

Para comparar el rendimiento de esta función con el de la opción propuesta en la respuesta aceptada, vea este violín y este violín para obtener puntos de referencia.

Solo para navegadores modernos

En los navegadores modernos, ahora puede hacer esto usando el String.prototype.repeatmétodo:

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

Lea más sobre este método en MDN .

Esta opción es aún más rápida. Desafortunadamente, no funciona en ninguna versión de Internet Explorer. Los números en la tabla especifican la primera versión del navegador que soporta totalmente este método:

ingrese la descripción de la imagen aquí

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

Aunque la respuesta más votada es un poco más compacta, con este enfoque no tiene que agregar un elemento de matriz adicional.

Grzegorz Pawlik
fuente
1
Desafortunadamente, el método de relleno no es compatible con IE, y si no es compatible con IE, también puede usar el método de repetición.
Michiel
1
¿Por qué utilizar el método adicional fill()si lo hace lo mismo 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"
);
yckart
fuente
7

En ES2015 / ES6 puedes usar "*".repeat(n)

Así que solo agregue esto a sus proyectos, y estará listo para comenzar.

  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
fuente
SCRIPT5029: la longitud de la matriz debe ser un entero positivo finito cuando intente utilizar este enfoque,
reparado el
5

Otra forma interesante de repetir rápidamente n caracteres es usar la idea del algoritmo de exponenciación rápida:

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
fuente
¿Por qué dices "manera interesante"? ¿Qué es tan interesante aquí? Es la solución obvia, el ejemplo fundamental más básico de un programa de computadora.
vsync
2

Para repetir un valor en mis proyectos, uso repetir

Por ejemplo:

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

pero tenga cuidado porque este método se ha agregado a la especificación ECMAScript 6.

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

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

Esto es lo que uso:

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

Voy a ampliar la respuesta de @bonbon . Su método es una manera fácil de "agregar N caracteres a una cadena existente", en caso de que alguien necesite hacer eso. Por ejemplo, dado que "un google" es un 1 seguido de 100 ceros .

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: Debe agregar la longitud de la cadena original al condicional.

Bruno Bronosky
fuente
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);
Inmundicia
fuente
0

También se puede usar como una sola línea:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}
Zarzaparrilla
fuente
En cualquier concurso "for" es más rápido que "while". :-)
junio
0

En CoffeeScript:

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

así es como puede llamar a una función y obtener el resultado con la ayuda de Array () y join ()

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

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

Amir danés
fuente
-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
fuente
1
Esto sobrescribe String.prototype.repeatque se incluye de forma nativa en los navegadores actuales. Además, ¿por qué minificarlo? No necesita escribirlo todo en una línea.
Licuadora
No hay función de 'repetición' en IE, por lo que se requiere un prototipo.
Caglayan ALTINCI
-3

Aquí hay una versión ES6

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

Maxali
fuente