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.

Steve
fonte

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

Jason Orendorff
fonte
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")

Salvador Dalí
fonte
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)  )

Kennebec
fonte
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;
  }
}
Konstantin Victorov
fonte
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')

bombom
fonte
10

Se você não se opõe a incluir uma biblioteca em seu projeto, o lodash tem uma função de repetição.

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

https://lodash.com/docs#repeat

Nathan Danger
fonte
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

John Slegers
fonte
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.

Grzegorz Pawlik
fonte
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"
);
yckart
fonte
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()) 
    };
webdeb
fonte
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;
};
csharpfolk
fonte
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.

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

repeatString(3,'x'); // => xxx
repeatString(10,'🌹'); // => "🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹"
alejandro
fonte
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('');
    }
Koushik Das
fonte
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.

Bruno Bronosky
fonte
0

O Lodash oferece uma funcionalidade semelhante à função repeat () do Javascript, que não está disponível em todos os navegadores. É chamado _.repeat e está disponível desde a versão 3.0.0:

_.repeat('a', 10);
0x4a6f4672
fonte
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);
Sujeira
fonte
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;
}
Salsaparrilha
fonte
Em qualquer concurso "for" é mais rápido que "while". :-)
junihh
0

No CoffeeScript:

( 'a' for dot in [0..10]).join('')
David Mendez
fonte
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))

Amir Danish
fonte
-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
fonte
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))

Maxali
fonte