Karakteri N Kere Tekrarla


602

Perl'de sözdizimini kullanarak bir karakteri birden çok kez tekrarlayabilirim:

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

Bunu Javascript ile yapmanın basit bir yolu var mı? Açıkçası bir işlevi kullanabilirim, ancak herhangi bir yerleşik yaklaşım veya başka akıllı bir teknik olup olmadığını merak ediyordum.

Yanıtlar:


1201

Bu günlerde repeatdize yöntemi neredeyse her yerde uygulanmaktadır . ( Internet Explorer'da değildir .) Bu nedenle, eski tarayıcıları desteklemeniz gerekmedikçe şunları yazabilirsiniz:

"a".repeat(10)

Daha önce repeatbu hack'i kullandık:

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

(Dizi uzunluğu arasınaArray.join argüman koyduğundan, uzunluk 11 dizisinin size sadece 10 "a" s getirdiğini unutmayın.)

Simon ayrıca, bu jsperf'e göre , Safari ve Chrome'da (ancak Firefox'ta değil) bir for döngüsü kullanarak (biraz daha az özlü olmasına rağmen) bir karakteri birden çok kez tekrarlamanın daha hızlı olduğuna dikkat çekiyor .


4
Artı, sabit uzunluk yerine bir değişken kullanabilirsiniz - Dizi (20-len), diyelim ki 20'ye kadar bir dize yastığı.
John C

7
Döngü yöntemi daha hızlı olabilir ancak daha ayrıntılı olabilir. Artı, Dizi uzunluğu değişken olduğunda bunun genellikle yararlı olacağı düşünüldüğünde, ilk yorum için tüm upvotes tarafından şaşkınım, örneğinArray(rawValue.length + 1).join("*")
Dexygen 30:30 '

Aynı sonuçlar ürettiklerinden, bu 0 ve 1 durumunda çalışmaz.
Ryan

2
Formül Array(n+1).join("a"). N = 0 olduğunda, bu boş dize döndürür ve n = 1 olduğunda, geri döner "a". Bence her durumda işe yarıyor.
Jason Orendorff

1
@Neel JS motorlarının dize uzunluğuna bir sınır koymasıdır. Chrome ve Firefox'ta sınır 2 ^ 30'a yakındır (yaklaşık bir milyar). 10 ^ 12 bir trilyon.
Jason Orendorff

301

Yeni bir ES6 uyumunda, bunu tekrarla yapmak için yerel bir yolunuz olacak . Ayrıca ES6 şu anda sadece deneysel, bu özellik Edge, FF, Chrome ve Safari'de zaten mevcut

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

Ve kesinlikle tekrarlama işlevi mevcut değilse, eski-iyi kullanabilirsiniz Array(n + 1).join("abc")


54

Kendinizi çok tekrar ederseniz uygun:

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
Yerleşiklerin prototiplerini kirletmek kötü bir kodlama uygulamasıdır.
tuomassalo

3
@nurettin daha fazla tartışma için programmers.stackexchange.com/questions/104320/… adresine bakın . İmzası olan bir (düzgün bir şekilde kapsamlandırılmış) statik yardımcı işlevi eklerdim repeat(str, n).
tuomassalo

4
Parçayı kaldıracağım n= n || 1(veya ntanımsız olup olmadığını kontrol edeceğim), böylece tekrarlayabilirsiniz 0.
chodorowicz

3
Ayrıca Mozilla'nın ES6 için resmi çoklu dolgusuna da göz atın: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland

3
@ChrisV, String.repeatsadece Haziran 2015'e kadar kesinleştirilmemiş olan ES6'ya eklendi. Bu yüzden 2012'de yazdığımda
puanım

13

Performans açısından en iyi yol https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

Kısa versiyon aşağıdadır.

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

Mozilla'dan Çoklu Dolgu:

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

Bu iyi bir şey, ancak yeni yerel "tekrar" daha da hızlı ve hiçbir uygulamaya gerek yok, yine de teşekkürler!
Goty Metal

1
anlamını açıklayabilir count >>>= 1, pattern += pattern;misiniz? ne tür bir ifade?
Tsahi Asher

Peki bu yerel tekrar için bir çoklu dolgu, o zaman? Sadece if (!String.prototype.repeat) {başına ve }sonuna bir ekleyin .
trlkly

>>> = imzasız sağa kaydırma atamasıdır (sayım = sayı >>> 1 gibi) bkz: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004

12

Bir alternatif:

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

Birden fazla karakter tekrarlamanız gerekiyorsa, koşulunuzu çoğaltın:

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

NOT: olduğu gibi 1 ile aşmak zorunda değilsinizword = Array(11).join('a')



10

Tüm tarayıcılar için

Aşağıdaki işlev, kabul edilen yanıtta önerilen seçenekten çok daha hızlı çalışacaktır:

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

Bunu şu şekilde kullanırsınız:

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

Bu işlevin performansını, kabul edilen yanıtta önerilen seçenekle karşılaştırmak için, bkz. Bu Fiddle ve bu Fiddle karşılaştırmak için, karşılaştırmalar için bakın.

Yalnızca modern tarayıcılar için

Modern tarayıcılarda, şimdi String.prototype.repeatyöntemi kullanarak bunu yapabilirsiniz :

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

MDN'de bu yöntem hakkında daha fazla bilgi edinin .

Bu seçenek daha da hızlı. Ne yazık ki, Internet explorer'ın herhangi bir sürümünde çalışmıyor. Tablodaki sayılar, yöntemi tam olarak destekleyen ilk tarayıcı sürümünü belirtir:

resim açıklamasını buraya girin


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

En çok oy verilen cevap biraz daha kompakt olsa da, bu yaklaşımla fazladan bir dizi öğesi eklemek zorunda değilsiniz.


1
Ne yazık ki, doldurma yöntemi IE'de desteklenmez ve IE uyumlu değilseniz tekrarlama yöntemini de kullanabilirsiniz.
Michiel

1
fill()join("a")
Yalnızla

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

ES2015 / ES6'da şunları kullanabilirsiniz: "*".repeat(n)

Bunu sadece projelerinize ekleyin ve hazırsınız.

  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: Bu yaklaşımı kullanmaya çalıştığınızda dizi uzunluğu sonlu bir pozitif tam sayı olmalıdır
andrepaulo

5

N karakterini hızlı bir şekilde tekrar etmenin bir başka ilginç yolu , hızlı üs alma algoritmasından gelen fikri kullanmaktır:

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

Neden "ilginç yol" diyorsun? burada bu kadar ilginç olan ne? bir bilgisayar programının en temel temel örneği olan bariz çözümdür.
vsync

2

Projelerimdeki bir değeri tekrarlamak için tekrar kullanıyorum

Örneğin:

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

ancak bu yöntem ECMAScript 6 spesifikasyonuna eklendiğinden dikkatli olun.


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

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

1

İşte ne kullanıyorum:

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

0

@ Bonbon'un cevabı üzerine genişleyeceğim . Onun yöntemi, herkesin bunu yapması gerektiğinde, "mevcut bir dizeye N karakterleri eklemek" için kolay bir yoldur. Örneğin, "bir google" 1 ve ardından 100 sıfır olduğu için .

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>

Not: koşullu özgün dize uzunluğunu eklemeniz gerekir.



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

Tek astar olarak da kullanılabilir:

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

Herhangi bir yarışmada "for", "while" 'dan daha hızlıdır. :-)
junihh


0

Array () ve join () yardımıyla bir işlevi çağırabilir ve sonucu elde edebilirsiniz.

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
Bu String.prototype.repeat, mevcut tarayıcılarda yerel olarak bulunan üzerine yazar . Ayrıca, neden küçültmeliyiz? Hepsini tek bir satıra yazmanıza gerek yok.
Blender

IE'de 'tekrar' özelliği yoktur, bu nedenle prototip gereklidir.
Çağlayan ALTINCI

-3

İşte bir ES6 sürümü

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.