Original address: http://www.davidflanagan.com/2009/08/string-multipli.html
Original author: David Flanagan
In Ruby , the "*" operator uses a string as the left parameter and a number as the right parameter to implement string repetition. For example, "Ruby" * 2 has the value "RubyRuby". This is only useful in a few places (for example, generating a table of ASCII characters such as hyphens), but is very concise. And it's better than writing a loop to concatenate strings n times - which seems very inefficient.
I just discovered a clever trick to do string multiplication in JavaScript:
String.prototype.times = function(n) {
return Array.prototype.join.call({length:n 1}, this);
};
"js".times(5) // => "jsjsjsjsjs"
This method is to call an Array whose elements are all "undefined" .join() behavior. But it doesn't actually create an array with n 1 "undefined" elements. It uses an anonymous object containing a length property, relying on the prototype function join() of the Array object. Because "Object" is not an array, join() cannot be called directly, so it has to be implemented through the prototype's call(). A simple version with the same effect is given below:
String.prototype.times = function(n) { return (new Array(n 1)).join(this);};
When we call Array’s constructor with one parameter , only sets the length of the array, but does not actually create the elements of the array.
I only tested it under Firefox and I estimate it will be more efficient than a normal loop, but I didn't benchmark it.
About the author
David Flanagan is a computer programmer who is obsessed with Java writing. He spends most of his time writing Java-related books. David earned degrees in computer science and engineering from MIT. He lives on the Pacific Northwest coast of the United States, between Seattle and Vancouver. His best-selling O'Reilly books include Java in a Nutshell, Java Foundation Classes in a Nutshell, Java Enterprise in a Nutshell, JavaScript: The Definitive Guide, JavaScript Pocket Reference, and The Ruby Programming Language" etc.
My comments
If efficiency is a concern, slightly optimizing the loop iteration may be more efficient. For example, the algorithm complexity of the following recursive call is O(log2n). The test result under Google Chrome is that it executes faster than David's method, but I have to admit that his method is very elegant!
String.prototype.times = function(n) {
if ( n == 1 ) {
return this;
}
var midRes = this.times(Math.floor(n/2));
midRes = midRes;
if ( n % 2 ) {
midRes = this;
}
return midRes;
}
Postscript
David adopted my suggestion, and he Wrote a non-recursive version for us. Please see the original text of his blog: http://www.davidflanagan.com/2009/08/good-algorithms.html
Contact information
My email, welcome to write to me (redraiment@gmail.com)