[javascript] Create a string of variable length, filled with a repeated character

So, my question has been asked by someone else in it's Java form here: Java - Create a new String instance with specified length and filled with specific character. Best solution?

. . . but I'm looking for its JavaScript equivalent.

Basically, I'm wanting to dynamically fill text fields with "#" characters, based on the "maxlength" attribute of each field. So, if an input has has maxlength="3", then the field would be filled with "###".

Ideally there would be something like the Java StringUtils.repeat("#", 10);, but, so far, the best option that I can think of is to loop through and append the "#" characters, one at a time, until the max length is reached. I can't shake the feeling that there is a more efficient way to do it than that.

Any ideas?

FYI - I can't simply set a default value in the input, because the "#" characters need to clear on focus, and, if the user didn't enter a value, will need to be "refilled" on blur. It's the "refill" step that I'm concerned with

This question is related to javascript html string

The answer is


Unfortunately although the Array.join approach mentioned here is terse, it is about 10X slower than a string-concatenation-based implementation. It performs especially badly on large strings. See below for full performance details.

On Firefox, Chrome, Node.js MacOS, Node.js Ubuntu, and Safari, the fastest implementation I tested was:

function repeatChar(count, ch) {
    if (count == 0) {
        return "";
    }
    var count2 = count / 2;
    var result = ch;

    // double the input until it is long enough.
    while (result.length <= count2) {
        result += result;
    }
    // use substring to hit the precise length target without
    // using extra memory
    return result + result.substring(0, count - result.length);
};

This is verbose, so if you want a terse implementation you could go with the naive approach; it still performs betweeb 2X to 10X better than the Array.join approach, and is also faster than the doubling implementation for small inputs. Code:

// naive approach: simply add the letters one by one
function repeatChar(count, ch) {
    var txt = "";
    for (var i = 0; i < count; i++) {
        txt += ch;
    }
    return txt;
}

Further information:


I would create a constant string and then call substring on it.

Something like

var hashStore = '########################################';

var Fiveup = hashStore.substring(0,5);

var Tenup = hashStore.substring(0,10);

A bit faster too.

http://jsperf.com/const-vs-join


Based on answers from Hogan and Zero Trick Pony. I think this should be both fast and flexible enough to handle well most use cases:

var hash = '####################################################################'

function build_string(length) {  
    if (length == 0) {  
        return ''  
    } else if (hash.length <= length) {  
        return hash.substring(0, length)  
    } else {  
        var result = hash  
        const half_length = length / 2  
        while (result.length <= half_length) {  
            result += result  
        }  
        return result + result.substring(0, length - result.length)  
    }  
}  

A great ES6 option would be to padStart an empty string. Like this:

var str = ''.padStart(10, "#");

Note: this won't work in IE (without a polyfill).


You can use the first line of the function as a one-liner if you like:

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

Version that works in all browsers

This function does what you want, and performs a lot faster than the option suggested in the accepted answer :

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

You use it like this :

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

To compare the performance of this function with that of the option proposed in the accepted answer, see this Fiddle and this Fiddle for benchmarks.

Version for moderns browsers only

In modern browsers, you can now also do this :

var repeatedCharacter = "a".repeat(10) };

This option is even faster. However, unfortunately it doesn't work in any version of Internet explorer.

The numbers in the table specify the first browser version that fully supports the method :

enter image description here


For Evergreen browsers, this will build a staircase based on an incoming character and the number of stairs to build.
function StairCase(character, input) {
    let i = 0;
    while (i < input) {
        const spaces = " ".repeat(input - (i+1));
        const hashes = character.repeat(i + 1);
        console.log(spaces + hashes);
        i++;
    }
}

//Implement
//Refresh the console
console.clear();
StairCase("#",6);   

You can also add a polyfill for Repeat for older browsers

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

Give this a try :P

_x000D_
_x000D_
s = '#'.repeat(10)_x000D_
_x000D_
document.body.innerHTML = s
_x000D_
_x000D_
_x000D_


ES2015 the easiest way is to do something like

'X'.repeat(data.length)

X being any string, data.length being the desired length.

see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript