24 07 2015
Obscure way to repeat string ( till 32 times )
Have you ever needed to repeat a string or character multiple times? Some times I have this need ( don’t ask why ) and it was always annoying for me to do this. For such a simple operation, you have to write for loop
and concatenate string. I know, there is now repeat
available in javascript, but it’s only starting with ES6 (ES2015) which is not available everywhere.
var repeat = function (times, str) { var result = ''; for (var i = 0; i < times; i++) { result += str; } return result;
But today after thinking a while I’ve found much more cleaner and faster way to do that. For rescue bit shifting operations comes into scene. Look at that beauty:
var repeat = function (times, str) { return (1 << (times - 1)).toString(2).replace(/./g, str); }
Doesn’t it looks cute? Let’s see how is this working.
There are two ways in repeating a string: it can be buildup using a for loop or it can be created using a replacement method.
The first one we all know, but the second one is what makes foundation of this trick.
We can take any string ‘string’ and replace any character of it with any other character or any string:
'string'.replace(/./g, 'new string');
This will repeat our ‘new string’ 6 times, because ‘string’ has 6 characters. In order to make repetition adjustable, we have to generate string with the number of characters we want to have repetition.
To create an input string, I’ve decided to use bit-shifting operation and represent bits as a characters. I won’t describe the idea behind bitshifting in details, but in short it looks like this.
Since any digit contains of a bits, it’s is possible to do bits manipulation. For example: number 2
is represented in bits as 00000010
. If we apply bitshift operator << to this number, all the bits are going to be shifting ‘n’ times to the left. So shifting 2 << 5
times, will make 01000000
. In order to see this bits, JavaScript provides toString method with operand. If you pass 2 to it, then it will represent digit in binary format.
(2).toString(2) // will be 10 (5).toString(2) // will be 1000000
Now that we know how bitshifting works and how to represent it as a string, we can easily create string with ‘n’ characters.
(1 << (n - 1)).toString(2);
That said, I have to note, that bitshifting in Javascript only works till 31 bits, then it bits get overflowed. That’s the reason why it’s only possible to repeat string 31 times using this approach:
(1 << 32).toString(2); // will be 1 again
Only what is left is to replace any character of this string with the string we need.
var repeat = function (times, str) { return (1 << (times - 1)).toString(2).replace(/./g, str); }
Using generators for node.js style callbacks Removing branches in git which are no longer in the GitHub (git)