420

In Python, where [2] is a list, the following code gives this output:

[2] * 5 # Outputs: [2,2,2,2,2]

Does there exist an easy way to do this with an array in JavaScript?

I wrote the following function to do it, but is there something shorter or better?

var repeatelem = function(elem, n){
    // returns an array with element elem repeated n times.
    var arr = [];

    for (var i = 0; i <= n; i++) {
        arr = arr.concat(elem);
    };

    return arr;
};
Sebastian Simon
  • 14,320
  • 6
  • 42
  • 61
Curious2learn
  • 26,027
  • 37
  • 97
  • 121
  • 4
    Possible duplicate: http://stackoverflow.com/questions/1295584/most-efficient-way-to-create-a-zero-filled-javascript-array – Larry Battle Sep 19 '12 at 21:28
  • possible duplicate: [stackoverflow.com/questions/1877475/repeat-character-n-times](http://stackoverflow.com/questions/1877475/repeat-character-n-times) – Benkinass May 17 '14 at 14:40

26 Answers26

919

In ES6 using Array fill() method

Array(5).fill(2)
//=> [2, 2, 2, 2, 2]
Niko Ruotsalainen
  • 30,972
  • 4
  • 20
  • 27
158
>>> Array.apply(null, Array(10)).map(function(){return 5})
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
>>> //Or in ES6
>>> [...Array(10)].map((_, i) => 5)
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
Alex Taylor
  • 7,080
  • 4
  • 23
  • 37
Janus Troelsen
  • 17,537
  • 13
  • 121
  • 177
  • 9
    Silly question, but why new Array(10).map does not work? – blazkovicz Jul 10 '15 at 08:39
  • 2
    blazkovicz, see [zertosh's comment on this answer](http://stackoverflow.com/a/13735425/20712) for the reason. – Ross Rogers Jul 14 '15 at 18:24
  • 7
    With ES6, this can be "upgraded" to `Array(...Array(10)).map(() => 5)` with the spread operator or also to `Array.from(Array(10)).map(() => 5)` – Christophe Vidal Oct 28 '15 at 11:42
  • 7
    According to [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from), you can just like this: `Array.from({length: 10}, () => 5);` – Plusb Preco Dec 25 '15 at 09:49
  • 3
    @blazkovicz Array(10) creates an array of `lenght = 10` without any enumerable properties. `.map` only works on enumerable properties. The `.apply` method takes this array, and maps it into an `arguments array` (an array-like object) to be passed to the `Array` constructor function. The arguments array can't be sparse so the missing properties get set to `undefined` and become enumerable. Now we can use `.map` like intended – CervEd Oct 23 '16 at 00:19
  • Slight modification on @ChristopheVidal's comment: `[...Array(10)].map(()=>5)` – Steve Ladavich Jan 03 '17 at 06:59
  • Please, note that ES6 version isn't work in typescript! – MaxXx1313 Nov 15 '18 at 16:07
108

you can try:

Array(6).join('a').split(''); // returns ['a','a','a','a','a'] (5 times)

Update (01/06/2018):

Now you can have a set of characters repeating.

new Array(5).fill('a'); // give the same result as above;
// or
Array.from({ length: 5 }).fill('a')

Note: Check more about fill(...) and from(...) for compatibility and browser support.

Update (05/11/2019):

Another way, without using fill or from, that works for string of any length:

Array.apply(null, Array(3)).map(_ => 'abc') // ['abc', 'abc', 'abc']

Same as above answer. Adding for sake of completeness.

Vivek
  • 4,316
  • 2
  • 15
  • 27
  • 2
    Nice. Shortest and simpler. – Johann Echavarria Oct 27 '14 at 21:59
  • 2
    +1 for simple handling. A shame that you cannot create an array of empty strings out of that. Apart from that very smart... – Quicker Oct 28 '14 at 20:38
  • 1
    Array(6).join('a').split('a') gives me array of empty string. – Vivek Nov 04 '14 at 06:53
  • 18
    This only works for 1 char strings, so it doesn't answer the question completely. – az_ May 21 '15 at 23:44
  • Is each "a" a separate object? Or does it reference the same object? – Alfonso Vergara Sep 09 '16 at 19:58
  • 3
    @AlfonsoVergara: In Javascript, String is a primitive (value-semantic) type; there's no way to get two strings to reference the same data (because strings *aren't* references in Javascript; they're values). You do have to watch out for reference semantics with objects and lists, but not with strings. – Quuxplusone Sep 11 '16 at 07:37
65

You can do it like this:

function fillArray(value, len) {
  if (len == 0) return [];
  var a = [value];
  while (a.length * 2 <= len) a = a.concat(a);
  if (a.length < len) a = a.concat(a.slice(0, len - a.length));
  return a;
}

It doubles the array in each iteration, so it can create a really large array with few iterations.


Note: You can also improve your function a lot by using push instead of concat, as concat will create a new array each iteration. Like this (shown just as an example of how you can work with arrays):

function fillArray(value, len) {
  var arr = [];
  for (var i = 0; i < len; i++) {
    arr.push(value);
  }
  return arr;
}
Guffa
  • 640,220
  • 96
  • 678
  • 956
  • 15
    It's much more efficient to allocate all of the entries up front, with `arr = new Array(len);`, then assign to them by index in the loop, i.e. `arr[i] = value;`. That way you only pay O(n) rather than having to keep reallocating the array as it grows. In general, it's always better to avoid growing arrays by appending when possible. If you know the final size, use it. – Tom Karzes Aug 08 '16 at 20:01
  • 62
    `Array.from({length:5}).map(x => 2)` – noobninja Jan 05 '19 at 18:07
  • 3
    @noobninja: great solution; you should re-enter it as an answer so it can be upvoted. – jsalvata Sep 09 '19 at 08:05
  • Here's an optimised version of the latter: `function fillArray(value, len) { for (let n = [], u = 0; u < len; u++) n.push(value); return n }` – undefined Jan 14 '21 at 17:40
41

Array.from({length:5}, i => 1) // [1, 1, 1, 1, 1]

or create array with increasing value

Array.from({length:5}, (e, i)=>i) // [0, 1, 2, 3, 4]

Thomson
  • 18,073
  • 19
  • 75
  • 125
  • Nice, this is the best approach if you need the element to dynamic – IliasT Apr 22 '19 at 20:44
  • `Array.from({length:5}, i => 1)` => `i` is is `undefined` since it represents empty value `Array.from({length:5}, (e, i)=>i)` => `e` is `undefined` since it represents empty value. It should be `Array.from({length:5}, v => 1)` and `Array.from({length:5}, (v, i)=>i)` – Rafal Enden Jun 05 '19 at 16:22
36

In lodash it's not so bad:

_.flatten(_.times(5, function () { return [2]; }));
// [2, 2, 2, 2, 2]

EDIT: Even better:

_.times(5, _.constant(2));
// [2, 2, 2, 2, 2]

EDIT: Even better:

_.fill(Array(5), 2);
Droogans
  • 6,701
  • 5
  • 36
  • 60
31

...and Array.fill() comes to the rescue!

Used to write it all manually before knowing this one ‍♂️


Array(6).fill('')   =>  ['','','','','','']

Array(3).fill({ value: 2 })   =>  [{ value: 2 },{ value: 2 },{ value: 2 }]

You can also easily create a sequential array using fill() + map()


Array(4).fill('').map((_, i) => i + ' ')  =>  ['0 ','1 ','2 ','3 ']


Array(3).fill(' ').map((flower, i) => i + flower)  =>  ['0 ','1 ','2 ']

22

If you need to repeat an array, use the following.

Array(3).fill(['a','b','c']).flat() 

will return

Array(9) [ "a", "b", "c", "a", "b", "c", "a", "b", "c" ]
etoxin
  • 3,828
  • 2
  • 31
  • 45
17

[c] * n can be written as:

Array(n+1).join(1).split('').map(function(){return c;})

so for [2] * 5

Array(6).join(1).split('').map(function(){return 2;})
Ingo Bürk
  • 16,020
  • 5
  • 56
  • 88
brook hong
  • 543
  • 6
  • 12
11

You can also extend the functionality of Array like so:

Array.prototype.fill = function(val){
    for (var i = 0; i < this.length; i++){
        this[i] = val;
    }
    return this;
};
// used like:
var arry = new Array(5)​.fill(2);
// or
var arry = new Array(5);
arry.fill(2);


​console.log(arry);​ //[2, 2, 2, 2, 2] 

I should note that extending the functionality of built-in objects can cause problems if you are working with 3rd-party libraries. Always weigh this into your decisions.

Shmiddty
  • 13,349
  • 1
  • 32
  • 52
  • Note that if you pass an object into `fill` each index in the array will refer to the same object, so changing one will change all of them. This isn't too hard to solve if it becomes an issue. – Shmiddty Sep 19 '12 at 22:00
  • I don't get why many javascript users are unaware of the requirement not to prototype native functions. – brooNo Aug 13 '15 at 13:46
  • There is no such "requirement". It's merely a best practice when mixing libraries. – Shmiddty Aug 13 '15 at 16:15
  • 2
    A [fill method](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.fill) has been added in ES6. So I wouldn't recommend adding your own stuff to the prototype, you're gonna overwrite the faster and more capable version. – Janus Troelsen Aug 28 '15 at 11:03
  • @Janus you should post that answer. – JMM Oct 16 '15 at 00:48
  • 1
    @JanusTroelsen To avoid overwrite javascript or 3rd-party libraries you can check if exists prior to declare it. `if (!Array.prototype.fill) { }` – Oliver Jun 16 '16 at 15:56
  • @Oliver why not just use a real polyfill then? – Janus Troelsen Jun 16 '16 at 16:00
  • 1
    @JanusTroelsen What do you mean by "real polyfill"?. I used a polifyll. I mean: check for feature detection and implementation in case it is not. – Oliver Jun 16 '16 at 16:14
9

In the Node.js REPL:

> Array.from({length:5}).map(x => 2)
[ 2, 2, 2, 2, 2 ]
noobninja
  • 722
  • 9
  • 12
  • `Array.from({length: 5}, x => 2);` ref. [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Using_arrow_functions_and_Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Using_arrow_functions_and_Array.from) – noobninja Dec 16 '19 at 05:31
6

No easier way. You need to make a loop and push elements into the array.

Diodeus - James MacFarlane
  • 107,156
  • 31
  • 147
  • 171
5

In case you need to repeat an array several times:

var arrayA = ['a','b','c'];
var repeats = 3;
var arrayB = Array.apply(null, {length: repeats * arrayA.length})
        .map(function(e,i){return arrayA[i % arrayA.length]});
// result: arrayB = ['a','b','c','a','b','c','a','b','c']

inspired by this answer

Community
  • 1
  • 1
  • in es6, you can do ["abc".repeat(3)](https://github.com/lukehoban/es6features/blob/3478ee4c9cdcced16cd0325e5a7fb08e102063f1/README.md#math--number--string--array--object-apis) – Janus Troelsen Aug 28 '15 at 11:01
5

Use this function:

function repeatElement(element, count) {
    return Array(count).fill(element)
}
>>> repeatElement('#', 5).join('')
"#####"

Or for a more compact version:

const repeatElement = (element, count) =>
    Array(count).fill(element)
>>> repeatElement('#', 5).join('')
"#####"

Or for a curry-able version:

const repeatElement = element => count =>
    Array(count).fill(element)
>>> repeatElement('#')(5).join('')
"#####"

You can use this function with a list:

const repeatElement = (element, count) =>
    Array(count).fill(element)

>>> ['a', 'b', ...repeatElement('c', 5)]
['a', 'b', 'c', 'c', 'c', 'c', 'c']
Ken Mueller
  • 2,126
  • 1
  • 15
  • 25
2

Try This:

"avinash ".repeat(5).trim().split(" ");
Avinash
  • 1,580
  • 1
  • 13
  • 14
2

You can use the SpreadOpeator and the map() function to create an array with the same element repeated multiple times.

function fillArray(value,len){
       return [...Array(len).keys()].map(x=> value);
   }
AnishJoshi
  • 66
  • 4
1

This function creates an array of (length) elements where each element equals (value) as long as (value) is an integer or string of an integer. Any decimal numbers will be truncated. If you do want decimal numbers, replace "parseInt(" with "parseFloat("

function fillArray(length, intValue) {
     var vals = (new Array(length + 1)).join(intValue + '|').split('|').slice(0,length);
     for(var i = 0; i < length; i += 1) {
         vals[i] = parseInt(vals[i]);
     }
     return vals;
}

Examples:

fillArray(5, 7) // returns [7,7,7,7,7]
fillArray(5, 7.5) // returns [7,7,7,7,7]
fillArray(5, 200) // returns [200,200,200,200,200]
TxRegex
  • 2,157
  • 17
  • 19
1

I had problems with the mentioned methods when I use an array like

var array = ['foo', 'bar', 'foobar'];
var filled = array.fill(7);

//filled should be ['foo', 'bar', 'foobar', 'foo', 'bar', 'foobar', 'foo']

To get this I'm using:

Array.prototype.fill = function(val){
    var l = this.length;
    if(l < val){
        for(var i = val-1-l; i >= 0; i--){
            this[i+l] = this[i % l];
        }
    }
    return this;
};
Xaver
  • 9,590
  • 11
  • 47
  • 84
1

Another one-liner:

Array.prototype.map.call([]+Array(5+1),function(){ return '2'; })
Filip Hermans
  • 262
  • 1
  • 4
1

I discovered this today while trying to make a 2D array without using loops. In retrospect, joining a new array is neat; I tried mapping a new array, which doesn't work as map skips empty slots.

"#".repeat(5).split('').map(x => 0)

The "#" char can be any valid single character. The 5 would be a variable for the number of elements you want. The 7 would be the value you want to fill your array with.

The new fill method is better, and when I coded this I didn't know it existed, nor did I know repeat is es6; I'm going to write a blog post about using this trick in tandem with reduce to do cool things.

http://jburger.us.to/2016/07/14/functionally-create-a-2d-array/

Magical Gordon
  • 274
  • 1
  • 8
1

var finalAry = [..."2".repeat(5).split("")].map(Number);
console.log(finalAry);
Amaldev ps
  • 217
  • 2
  • 10
0

If you are using a utlity belt like lodash/underscore you can do it like this :)

let result = _.map(_.times(foo), function() {return bar})
0

Can be used as a one-liner too:

function repeat(arr, len) {
    while (arr.length < len) arr = arr.concat(arr.slice(0, len-arr.length));
    return arr;
}
Sarsaparilla
  • 4,860
  • 1
  • 25
  • 17
0

Improving on Vivek's answer, this works for strings of any length, to populate an array of length n: Array(n+1).join('[string to be repeated][separator]').split('[separator]').slice(0, n)

Tigregalis
  • 440
  • 2
  • 8
0

This could be another answers.

let cards = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"];

let totalCards = [...cards, ...cards, ...cards, ...cards];

Zenit
  • 415
  • 1
  • 6
  • 15
-1

I needed a way to repeat/loop an array (with n items) m times.

For example, distributing a list (of persons) to a week/month. Let's say I have 3 names, and I want to them to repeat in a week:

fillArray(["Adam", "Blair", "Curtis"], 7); // returns ["Adam", "Blair", "Curtis", "Adam", "Blair", "Curtis", "Adam"]

function fillArray(pattern, count) {
    let result = [];
    if (["number", "string"].includes(typeof pattern)) {
        result = new Array(5);
        result.fill(pattern);
    }
    else if (pattern instanceof Array) {
        for (let i = 0; i < count; i++) {
            result = result.concat(pattern);
        }
        result = result.slice(0, count);
    }
    return result;
}

fillArray("a", 5);        // ["a", "a", "a", "a", "a"]
fillArray(1, 5);          // [1, 1, 1, 1, 1]
fillArray(["a", "b"], 5); // ["a", "b", "a", "b", "a"]
akinuri
  • 7,673
  • 10
  • 47
  • 80