Ulangi Karakter N Kali

602

Di Perl saya dapat mengulangi karakter beberapa kali menggunakan sintaks:

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

Apakah ada cara sederhana untuk melakukannya di Javascript? Saya jelas dapat menggunakan fungsi, tetapi saya bertanya-tanya apakah ada pendekatan bawaan, atau teknik pintar lainnya.

Steve
sumber

Jawaban:

1201

Saat ini, repeatmetode string diimplementasikan hampir di semua tempat. (Ini tidak ada di Internet Explorer .) Jadi kecuali Anda perlu mendukung browser lama, Anda bisa menulis:

"a".repeat(10)

Sebelumnya repeat, kami menggunakan retasan ini:

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

(Perhatikan bahwa array dengan panjang 11 hanya memberi Anda 10 "a", karena Array.joinmenempatkan argumen di antara elemen-elemen array.)

Simon juga menunjukkan bahwa menurut jsperf ini , tampaknya lebih cepat di Safari dan Chrome (tetapi bukan Firefox) untuk mengulangi karakter beberapa kali hanya dengan menambahkan menggunakan for for (walaupun agak kurang ringkas).

Jason Orendorff
sumber
4
Plus, Anda dapat menggunakan variabel alih-alih panjang tetap - Array (20-len), katakan untuk menambahkan string hingga 20.
John C
7
Metode loop mungkin lebih cepat tetapi lebih bertele-tele. Ditambah lagi saya bingung dengan semua upvotes untuk komentar pertama, mengingat bahwa ketika ini umumnya akan berguna ketika panjang Array adalah variabel, misalnyaArray(rawValue.length + 1).join("*")
Dexygen
Ini tidak berfungsi dalam kasus 0 dan 1, karena mereka menghasilkan hasil yang identik.
Ryan
2
Rumusnya adalah Array(n+1).join("a"). Ketika n = 0, ini mengembalikan string kosong, dan ketika n = 1, itu mengembalikan "a". Jadi saya pikir itu berfungsi dalam semua kasus.
Jason Orendorff
1
@Neel Itu karena mesin JS memberlakukan batasan pada panjang string. Di Chrome dan Firefox, batasnya mendekati 2 ^ 30 (sekitar satu miliar). 10 ^ 12 adalah satu triliun.
Jason Orendorff
301

Dalam harmoni ES6 baru, Anda akan memiliki cara asli untuk melakukan ini dengan berulang . Juga ES6 sekarang hanya eksperimental, fitur ini sudah tersedia di Edge, FF, Chrome dan Safari

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

Dan tentunya jika fungsi repeat tidak tersedia Anda bisa menggunakan yang lama-bagus Array(n + 1).join("abc")

Salvador Dali
sumber
54

Nyaman jika Anda sering mengulangi:

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
sumber
53
Ini adalah praktik pengkodean yang buruk untuk mencemari prototipe bawaan.
tuomassalo
3
@nurettin lihat programmers.stackexchange.com/questions/104320/… untuk diskusi lebih lanjut. Saya akan menambahkan fungsi pembantu statis (dengan cakupan yang tepat), dengan tanda tangan repeat(str, n).
tuomassalo
4
Saya akan menghapus n= n || 1bagian (atau memeriksa apakah ntidak terdefinisi), sehingga Anda juga dapat mengulangi 0kali.
chodorowicz
3
Lihat juga polyfill resmi Mozilla untuk ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Eirik Birkeland
3
@ ChrisV, String.repeathanya ditambahkan dalam ES6, yang belum selesai sampai Juni 2015. Jadi saya pikir poin saya valid ketika saya menulisnya pada tahun 2012. :)
tuomassalo
13

Cara yang paling berkinerja baik adalah https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

Versi singkat di bawah.

  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 dari 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
sumber
Ini bagus, tetapi "pengulangan" asli yang baru lebih cepat dan tidak perlu implementasi, terima kasih!
Goty Metal
1
dapatkah Anda menguraikan arti dari count >>>= 1, pattern += pattern;? pernyataan macam apa itu?
Tsahi Asher
Jadi ini adalah polyfill untuk pengulangan asli, lalu? Tambahkan saja if (!String.prototype.repeat) {ke awal dan }ke akhir.
trlkly
>>> = adalah penugasan shift kanan yang tidak ditandatangani (seperti dalam hitung = hitung >>> 1) lihat: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1441004
12

Alternatifnya adalah:

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

Jika Anda perlu mengulang beberapa karakter, gandakan persyaratan Anda:

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

CATATAN: Anda tidak perlu melakukan overshoot oleh 1 seperti padaword = Array(11).join('a')

bonbon
sumber
10

Jika Anda tidak menentang untuk memasukkan perpustakaan dalam proyek Anda, lodash memiliki fungsi berulang.

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

https://lodash.com/docs#repeat

Bahaya Nathan
sumber
10

Untuk semua browser

Fungsi berikut akan melakukan jauh lebih cepat daripada opsi yang disarankan dalam jawaban yang diterima:

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

Anda akan menggunakannya seperti ini:

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

Untuk membandingkan kinerja fungsi ini dengan opsi yang diusulkan dalam jawaban yang diterima, lihat Fiddle dan Fiddle ini untuk tolok ukur.

Hanya untuk peramban modern

Di browser modern, Anda sekarang dapat melakukan ini menggunakan String.prototype.repeatmetode:

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

Baca lebih lanjut tentang metode ini di MDN .

Opsi ini bahkan lebih cepat. Sayangnya, itu tidak berfungsi di versi Internet Explorer apa pun. Angka-angka dalam tabel menentukan versi browser pertama yang sepenuhnya mendukung metode ini:

masukkan deskripsi gambar di sini

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

Meskipun jawaban yang paling banyak dipilih sedikit lebih kompak, dengan pendekatan ini Anda tidak perlu menambahkan item array tambahan.

Grzegorz Pawlik
sumber
1
Sayangnya, metode pengisian tidak didukung di IE, dan jika Anda tidak kompatibel dengan IE Anda bisa menggunakan metode pengulangan.
Michiel
1
Mengapa Anda menggunakan metode tambahan fill()jika Anda melakukan hal yang sama dengan join("a")sendirian ...
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"
);
yaart
sumber
7

Di ES2015 / ES6 Anda dapat menggunakan "*".repeat(n)

Jadi tambahkan saja ini ke proyek Anda, dan Anda siap melakukannya.

  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
sumber
SCRIPT5029: Panjang array harus menjadi bilangan bulat positif terbatas ketika mencoba menggunakan pendekatan ini
andrepaulo
5

Cara lain yang menarik untuk mengulangi n karakter dengan cepat adalah dengan menggunakan ide dari algoritma eksponensial cepat:

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
sumber
Mengapa Anda mengatakan "cara yang menarik"? apa yang begitu menarik di sini? itu adalah solusi jelas, contoh mendasar paling mendasar dari program komputer.
vsync
2

Untuk mengulang nilai dalam proyek saya, saya menggunakan repeat

Sebagai contoh:

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

tapi hati-hati karena metode ini telah ditambahkan ke spesifikasi ECMAScript 6.

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

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

Inilah yang saya gunakan:

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

Saya akan memperluas jawaban @ bonbon . Metodenya adalah cara mudah untuk "menambahkan N karakter ke string yang ada", kalau-kalau ada yang perlu melakukan itu. Misalnya karena "a google" adalah 1 diikuti oleh 100 nol .

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>

CATATAN: Anda harus menambahkan panjang string asli ke kondisional.

Bruno Bronosky
sumber
0

Lodash menawarkan fungsionalitas yang serupa dengan fungsi Javascript repeat () yang tidak tersedia di semua browser. Ini disebut _.ulangi dan tersedia sejak versi 3.0.0:

_.repeat('a', 10);
0x4a6f4672
sumber
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);
Kotoran
sumber
0

Dapat digunakan sebagai one-liner juga:

function repeat(str, len) {
    while (str.length < len) str += str.substr(0, len-str.length);
    return str;
}
Sarsaparila
sumber
Pada setiap kontes "untuk" lebih cepat dari "sementara". :-)
junihh
0

Dalam CoffeeScript:

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

ini adalah bagaimana Anda dapat memanggil suatu fungsi dan mendapatkan hasilnya dengan bantuan Array () dan bergabung ()

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

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

Amir Denmark
sumber
-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
sumber
1
Timpa ini String.prototype.repeatyang secara bawaan termasuk dalam browser saat ini. Juga, mengapa dikurangi? Anda tidak perlu menulis semuanya dalam satu baris.
Blender
Tidak ada fitur 'ulangi' di IE, jadi prototipe diperlukan.
Caglayan ALTINCI
-3

Ini adalah versi ES6

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

Maxali
sumber