views:

6587

answers:

6

What is the best or most concise method for returning a string repeated an arbitrary amount of times?

The following is my best shot so far:

function repeat(s, n){
    var a = [];
    while(a.length < n){
        a.push(s);
    }
    return a.join('');
}
A: 

Why not just build a string with s n times?

mspmsp
+1  A: 
function repeat(s, n) { var r=""; for (var a=0;a<n;a++) r+=s; return r;}
Joel Coehoorn
Isn't string concatenation costly? That's at least the case in Java.
Vijay Dev
+42  A: 

I'd put this function onto the String object directly. Instead of creating an array, filling it, and joining it with an empty char, just create an array of the proper length, and join it with your desired string. Same result, less process!

String.prototype.repeat = function( num )
{
    return new Array( num + 1 ).join( this );
}

alert( "string to repeat\n".repeat( 4 ) );
Peter Bailey
I try not to extend native objects, but otherwise this is a beautiful solution. Thanks!
brad
That's very clever. I can't wait to get a chance to use it.
Joel Anair
@ brad - why not? You'd rather pollute the global namespace with a function that has a fairly well-defined home (the String object)?
Peter Bailey
BaileyP: Extending the builtin objects breaks things. In the case of string it's not too bad, but for Array and so on, you cause problems
Orion Edwards
What if someone else wants to define String.repeat to do something different? Maybe it's in a library you use or maybe another programmer on your team. It happens.
Joel Coehoorn
Actually, both of your arguments apply to the global namespace as well. If I'm going to expand a namespace and have potential collisions, I'd rather do it 1) not in global 2) in one that is relevant and 3) is easy to refactor. This means putting it on the String prototype, not in global.
Peter Bailey
one change I'd make to this function would be to put parseInt() around "num", since if you have a numeric string, you might get strange behaviour due to JS's type juggling. for example: "my string".repeat("6") == "61"
nickf
If you don't want to extend native objects, you could put the function on the String object instead, like this: `String.repeat = function(string, num){ return new Array(parseInt(num) + 1).join(string); };`. Call it like this: `String.repeat('/\', 20)`
Znarkus
A: 

/**
@desc: repeat string
@param: n - times
@param: d - delimiter
*/

String.prototype.repeat = function (n, d){
   return --n
     ? this+d+this.repeat(n,d)
     : ''+this
}

this is how to repeat string several times using delimeter.

Tumtu
+6  A: 

Expanding P.Bailey's solution:

String.prototype.repeat = function(num) {
    return new Array(isNaN(num)? 1 : ++num).join(this);
    }

This way you should be safe from unexpected argument types:

var foo = 'bar';
alert(foo.repeat(3));              // Will work, "barbarbar"
alert(foo.repeat('3'));            // Same as above
alert(foo.repeat(true));           // Same as foo.repeat(1)

alert(foo.repeat(0));              // This and all the following return an empty
alert(foo.repeat(false));          // string while not causing an exception
alert(foo.repeat(null));
alert(foo.repeat(undefined));
alert(foo.repeat({}));             // Object
alert(foo.repeat(function () {})); // Function

EDIT: Credits to jerone for his elegant ++num idea!

U-D13
Changed your's a little: `String.prototype.repeat = function(n){return new Array(isNaN(n) ? 1 : ++n).join(this);}`
jerone
Perfect! I'll update my post. Thanks, jerone!
U-D13
+1  A: 

Or use prototypejs http://api.prototypejs.org/language/string.html#times-instance_method

blavla
URL now: http://www.prototypejs.org/api/string/times
Neil