Repita o caractere N vezes


602

No Perl, posso repetir um caractere várias vezes usando a sintaxe:

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

Existe uma maneira simples de fazer isso em Javascript? Obviamente, posso usar uma função, mas fiquei imaginando se havia alguma abordagem integrada ou alguma outra técnica inteligente.

Respostas:


1201

Hoje em dia, o repeatmétodo string é implementado em quase todos os lugares. (Não está no Internet Explorer .) Portanto, a menos que você precise oferecer suporte a navegadores antigos, basta escrever:

"a".repeat(10)

Antes repeat, usamos esse hack:

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

(Observe que uma matriz de comprimento 11 fornece apenas 10 "a" s, pois Array.joincoloca o argumento entre os elementos da matriz.)

Simon também aponta que, de acordo com este jsperf , parece mais rápido no Safari e no Chrome (mas não no Firefox) repetir um caractere várias vezes, simplesmente anexando usando um loop for (embora um pouco menos conciso).


4
Além disso, você pode usar uma variável em vez de um comprimento fixo - Array (20-len), dizer a almofada uma corda até 20.
John C

7
O método loop pode ser mais rápido, mas é mais detalhado. Além disso, estou intrigado com todos os votos positivos para o primeiro comentário, considerando que quando isso geralmente será útil quando o comprimento da matriz for variável, por exemplo:Array(rawValue.length + 1).join("*")
Dexygen

Isso não funciona nos casos 0 e 1, pois eles produzem resultados idênticos.
Ryan

2
A fórmula é Array(n+1).join("a"). Quando n = 0, isso retorna a cadeia vazia e, quando n = 1, ele retorna "a". Então eu acho que funciona em todos os casos.
Jason Orendorff

1
@ Neel Isso ocorre porque os mecanismos JS impõem um limite no comprimento da string. No Chrome e Firefox, o limite é próximo de 2 ^ 30 (cerca de um bilhão). 10 ^ 12 é um trilhão.
Jason Orendorff

301

Em uma nova harmonia ES6, você terá uma maneira nativa de fazer isso com repetição . Também no ES6, agora apenas experimental, esse recurso está disponível no Edge, FF, Chrome e Safari

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

E certamente, se a função de repetição não estiver disponível, você poderá usar o antigo Array(n + 1).join("abc")


54

Conveniente se você se repetir bastante:

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
É uma má prática de codificação poluir os protótipos dos componentes internos.
tuomassalo

3
@ nurettin consulte programmers.stackexchange.com/questions/104320/… para mais discussões. Eu adicionaria uma função auxiliar estática (com escopo definido), com uma assinatura de repeat(str, n).
Tuomassalo 27/05

4
Eu removia a n= n || 1peça (ou verificava se não nestá definida), para que você também possa repetir os 0tempos.
21413 chodorowicz

3
Também dê uma olhada no polyfill oficial da Mozilla para ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland

3
@ChrisV, String.repeatfoi adicionado apenas no ES6, que não foi finalizado até junho de 2015. Acho que meu argumento foi válido quando o escrevi em 2012. :)
tuomassalo

13

A maneira mais econômica de desempenho é https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

A versão curta está abaixo.

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

Essa é boa, mas a nova "repetição" nativa é ainda mais rápida e não precisa de implementação, de qualquer forma, obrigada!
Goty Metal

1
você pode elaborar o significado de count >>>= 1, pattern += pattern;? que tipo de afirmação é essa?
Tsahi Asher

Então este é um polyfill para a repetição nativa, então? Basta adicionar um if (!String.prototype.repeat) {ao início e }ao fim.
trlkly

>>> = é uma atribuição de turno à direita não assinada (como em count = count >>> 1), consulte: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004

12

Uma alternativa é:

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

Se você precisar repetir vários caracteres, multiplique seu condicional:

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

NOTA: Você não precisa exceder em 1, como ocorre comword = Array(11).join('a')



10

Para todos os navegadores

A função a seguir terá um desempenho muito mais rápido que a opção sugerida na resposta aceita:

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

Você usaria assim:

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

Para comparar o desempenho desta função com o da opção proposta na resposta aceita, consulte este Fiddle e este Fiddle para obter referências.

Apenas para navegadores modernos

Nos navegadores modernos, agora você pode fazer isso usando o String.prototype.repeatmétodo:

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

Leia mais sobre esse método no MDN .

Esta opção é ainda mais rápida. Infelizmente, ele não funciona em nenhuma versão do Internet Explorer. Os números na tabela especificam a primeira versão do navegador que suporta totalmente o método:

insira a descrição da imagem aqui


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

Embora a resposta mais votada seja um pouco mais compacta, com essa abordagem, você não precisa adicionar um item de matriz extra.


1
Infelizmente, o método de preenchimento não é suportado no IE e, se você não for compatível com o IE, poderá usar o método de repetição.
Michiel

1
Por que você usaria o método extra de fill()se fazer o mesmo com join("a")sozinho ...
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

No ES2015 / ES6, você pode usar "*".repeat(n)

Então, basta adicionar isso aos seus projetos, e você estará pronto.

  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: comprimento de matriz deve ser um inteiro positivo finito quando tentar usar essa abordagem
andrepaulo

5

Outra maneira interessante de repetir rapidamente o caractere n é usar a ideia do algoritmo de exponenciação 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;
};

Por que você diz "maneira interessante"? o que é tão interessante aqui? é a solução óbvia, o exemplo fundamental mais básico de um programa de computador.
vsync

2

Para repetir um valor em meus projetos eu uso repeat

Por exemplo:

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

mas tenha cuidado, pois esse método foi adicionado à especificação do ECMAScript 6.


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

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

1

Aqui está o que eu uso:

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

0

Vou expandir a resposta do @ bonbon . Seu método é uma maneira fácil de "anexar N caracteres a uma string existente", caso alguém precise fazer isso. Por exemplo, como "a google" é 1 seguido por 100 zeros .

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: Você precisa adicionar o comprimento da seqüência original à condicional.



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

Também pode ser usado como uma linha:

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

Em qualquer concurso "for" é mais rápido que "while". :-)
junihh


0

é assim que você pode chamar uma função e obter o resultado com a ajuda de 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
Isso substitui String.prototype.repeatque é incluído nativamente nos navegadores atuais. Além disso, por que minificá-lo? Você não precisa escrever tudo em uma linha.
Blender

Nenhum recurso de 'repetição' no IE, portanto, é necessário um protótipo.
Caglayan ALTINCI

-3

Aqui está uma versão do ES6

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.