Lặp lại nhân vật N Times


602

Trong Perl tôi có thể lặp lại một ký tự nhiều lần bằng cú pháp:

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

Có cách nào đơn giản để thực hiện điều này trong Javascript không? Tôi rõ ràng có thể sử dụng một chức năng, nhưng tôi đã tự hỏi nếu có bất kỳ cách tiếp cận được xây dựng, hoặc một số kỹ thuật thông minh khác.

Câu trả lời:


1201

Ngày nay, repeatphương thức chuỗi được thực hiện ở hầu hết mọi nơi. (Nó không có trong Internet Explorer .) Vì vậy, trừ khi bạn cần hỗ trợ các trình duyệt cũ hơn, bạn chỉ cần viết:

"a".repeat(10)

Trước đây repeat, chúng tôi đã sử dụng bản hack này:

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

(Lưu ý rằng một mảng có độ dài 11 chỉ mang lại cho bạn 10 "a", vì Array.joinđặt đối số giữa các thành phần mảng.)

Simon cũng chỉ ra rằng theo jsperf này , có vẻ như nó nhanh hơn trong Safari và Chrome (chứ không phải Firefox) để lặp lại một ký tự nhiều lần bằng cách thêm vào bằng cách sử dụng vòng lặp for (mặc dù ngắn gọn hơn một chút).


4
Ngoài ra, bạn có thể sử dụng một biến thay vì độ dài cố định - Mảng (20-len), giả sử đệm một chuỗi lên đến 20.
John C

7
Phương thức lặp có thể nhanh hơn nhưng dài dòng hơn. Thêm vào đó, tôi cảm thấy bối rối với tất cả các upvote cho bình luận đầu tiên, xem xét rằng khi điều này thường sẽ hữu ích khi độ dài Mảng thay đổi, ví dụArray(rawValue.length + 1).join("*")
Dexygen

Điều này không hoạt động trong trường hợp 0 ​​và 1, vì chúng tạo ra kết quả giống hệt nhau.
Ryan

2
Công thức là Array(n+1).join("a"). Khi n = 0, điều này trả về chuỗi trống và khi n = 1, nó sẽ trả về "a". Vì vậy, tôi nghĩ rằng nó hoạt động trong tất cả các trường hợp.
Jason Orendorff

1
@Neel Đó là vì các công cụ JS áp đặt giới hạn về độ dài chuỗi. Trong Chrome và Firefox, giới hạn là gần 2 ^ 30 (khoảng một tỷ). 10 ^ 12 là một nghìn tỷ.
Jason Orendorff

301

Trong bản hòa âm ES6 mới, bạn sẽ có cách riêng để thực hiện điều này với lặp lại . Ngoài ra ES6 hiện chỉ mới thử nghiệm, tính năng này đã có sẵn trong Edge, FF, Chrome và Safari

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

Và chắc chắn nếu chức năng lặp lại không có sẵn, bạn có thể sử dụng old-good Array(n + 1).join("abc")


54

Thuận tiện nếu bạn lặp lại nhiều lần:

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
Đó là một thực tế mã hóa xấu để gây ô nhiễm nguyên mẫu của các nhà xây dựng.
tuomassalo

3
@nurettin xem lập trình viên.stackexchange.com/questions/104320/ để thảo luận thêm. Tôi muốn thêm một hàm trợ giúp tĩnh (có phạm vi chính xác), với chữ ký là repeat(str, n).
tuomassalo

4
Tôi sẽ xóa n= n || 1phần này (hoặc kiểm tra nếu nkhông xác định), vì vậy bạn cũng có thể lặp lại 0thời gian.
chodorowicz

3
Ngoài ra, hãy xem polyfill chính thức của Mozilla cho ES6: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Eirik Birkeland

3
@ChrisV, String.repeatchỉ được thêm vào ES6, chưa được hoàn thiện cho đến tháng 6 năm 2015. Vì vậy, tôi nghĩ rằng quan điểm của tôi là hợp lệ khi tôi viết nó vào năm 2012. :)
tuomassalo

13

Cách hiệu quả nhất là https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat

Phiên bản ngắn dưới đây.

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

Đây là một cái tốt, nhưng "lặp lại" bản địa mới thậm chí còn nhanh hơn và không cần thực hiện, dù sao cũng cảm ơn!
Kim loại Goty

1
bạn có thể giải thích ý nghĩa của count >>>= 1, pattern += pattern;? Đó là loại tuyên bố gì?
Tsahi Asher

Vì vậy, đây là một polyfill cho lặp lại bản địa, sau đó? Chỉ cần thêm một if (!String.prototype.repeat) {vào đầu và }cuối.
trlkly

>>> = là unsigned phân công dịch phải (như trong count = count >>> 1) xem: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
user1441004

12

Một thay thế là:

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

Nếu bạn cần lặp lại nhiều ký tự, nhân bội điều kiện của bạn:

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

LƯU Ý: Bạn không phải vượt quá 1 như vớiword = Array(11).join('a')



10

Đối với tất cả các trình duyệt

Hàm sau sẽ thực hiện nhanh hơn rất nhiều so với tùy chọn được đề xuất trong câu trả lời được chấp nhận:

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

Bạn sẽ sử dụng nó như thế này:

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

Để so sánh hiệu suất của chức năng này với tùy chọn được đề xuất trong câu trả lời được chấp nhận, hãy xem FiddleFiddle này để biết điểm chuẩn.

Chỉ dành cho trình duyệt hiện đại

Trong các trình duyệt hiện đại, bây giờ bạn có thể thực hiện việc này bằng String.prototype.repeatphương pháp:

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

Đọc thêm về phương pháp này trên MDN .

Tùy chọn này thậm chí còn nhanh hơn. Thật không may, nó không hoạt động trong bất kỳ phiên bản Internet explorer nào. Các số trong bảng chỉ định phiên bản trình duyệt đầu tiên hỗ trợ đầy đủ phương thức:

nhập mô tả hình ảnh ở đây


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

Mặc dù câu trả lời được bình chọn nhiều nhất là nhỏ gọn hơn một chút, nhưng với cách tiếp cận này, bạn không cần phải thêm một mục mảng.


1
Thật không may, phương thức điền không được hỗ trợ trong IE và nếu bạn không tương thích với IE, bạn cũng có thể sử dụng phương thức lặp lại.
Michiel

1
Tại sao bạn lại sử dụng phương thức bổ sung fill()nếu bạn làm tương tự với join("a")một mình ...
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

Trong ES2015 / ES6 bạn có thể sử dụng "*".repeat(n)

Vì vậy, chỉ cần thêm điều này vào các dự án của bạn, và bạn là tốt để đi.

  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: Độ dài mảng phải là số nguyên dương hữu hạn khi thử sử dụng phương pháp này
andrepaulo

5

Một cách thú vị khác để nhanh chóng lặp lại n ký tự là sử dụng ý tưởng từ thuật toán lũy thừa nhanh:

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

Tại sao bạn nói "cách thú vị"? có gì thú vị ở đây đó là giải pháp rõ ràng, ví dụ cơ bản nhất của chương trình máy tính.
vsync

2

Để lặp lại một giá trị trong các dự án của tôi, tôi sử dụng lặp lại

Ví dụ:

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

nhưng hãy cẩn thận vì phương pháp này đã được thêm vào đặc tả ECMAScript 6.


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

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

1

Đây là những gì tôi sử dụng:

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

0

Tôi sẽ mở rộng câu trả lời của @ bonbon . Phương pháp của anh ấy là một cách dễ dàng để "nối N ký tự vào một chuỗi hiện có", trong trường hợp bất cứ ai cần phải làm điều đó. Ví dụ: "google" là số 1 theo sau là 100 số không .

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>

LƯU Ý: Bạn phải thêm độ dài của chuỗi gốc vào điều kiện.



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

Có thể được sử dụng như một lớp lót quá:

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

Trên bất kỳ cuộc thi "cho" nào nhanh hơn "trong khi". :-)
Junihh


0

đây là cách bạn có thể gọi một hàm và nhận kết quả nhờ sự trợ giúp của Array () và tham gia ()

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
Điều này ghi đè lên String.prototype.repeatđiều đó thực sự bao gồm trong các trình duyệt hiện tại. Ngoài ra, tại sao lại giảm thiểu nó? Bạn không cần phải viết tất cả trong một dòng.
Máy xay sinh tố

Không có tính năng 'lặp lại' trong IE, do đó cần có nguyên mẫu.
Caglayan ALTINCI

-3

Đây là phiên bản ES6

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.