17

In python you can do:

arr = [1,2,3] * 3
print(arr)

output:

[1,2,3,1,2,3,1,2,3]

Is there a concise way of doing this in java script? The best I can think of is something like:

let arr2 = [...arr, ...arr, ...arr]

but if I wanted to do this 100 times it would be impractical. In python I would just multiply it by 100.

Oamar Kanji
  • 1,824
  • 6
  • 24
  • 39

6 Answers6

25

You could do this:

var repeated = [].concat(... new Array(100).fill([1, 2, 3]));

That creates an array of a given length (100 here) and fills it with the array to be repeated ([1, 2, 3]). That array is then spread as the argument list to [].concat().

Oh wait just

var repeated = new Array(100).fill([1, 2, 3]).flat();

would be a little shorter.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I like this because it is a one liner that is easy to read and makes sense. Coming from python this feels more natural to me. – Oamar Kanji Feb 28 '19 at 22:45
  • 2
    Note that [you can also omit the `new` keyword](https://stackoverflow.com/a/8205709/965834). – Jeto Feb 28 '19 at 22:48
  • 2
    @Jeto yes good point though I admit that that makes me irrationally uncomfortable – Pointy Feb 28 '19 at 22:49
  • 1
    I wonder how efficient this is. – Max Waterman Sep 07 '20 at 03:37
  • 1
    @MaxWaterman well if you want to do something to every element of an array, that's inherently a linear-time operation. – Pointy Sep 07 '20 at 12:57
  • @Pointy sure, but is it linear? It depends on how it is implemented. It seems to me it makes an array of pointers to new array of length 3, and then it goes through, yet again, to flatten it into a one dimensional array. As I said, I wonder if it is cleverer than that, or not. The Array.from() solution seems to be more obviously only a single traversal (make memory for the array, then assign to it). – Max Waterman Sep 08 '20 at 13:16
  • @MaxWaterman going through a list a fixed number of times is still O(n). `Array.from()` is also going to (internally) make a linear pass through the list. – Pointy Sep 08 '20 at 13:18
  • @Pointy Yeah, ok, linear, fair enough - but it seems to go through the (different?) arrays twice, while it isn't clear to me that Array.from() would go through twice (hence my question), or just once. I'll take your word for it if you think Nina's Array.from() method does two passes...not sure why it would but there you go - JavaScript is a funny animal. – Max Waterman Sep 09 '20 at 14:31
  • Note that 100 is not the 'length of the result array'. It is the number of times the supplied array gets "repeated" – Marnix.hoh Dec 07 '20 at 13:30
8

Use Array.from() to create an array with a length of the multiplier, where each item contains the original array. Then use Array.flat() to convert to a single array:

const multiplyArray = (arr, length) => 
  Array.from({ length }, () => arr).flat()

const arr = [1,2,3]
const arr2 = multiplyArray(arr, 3)

console.log(arr2)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
7

You could create an array with the wanted length and map the values.

var array = [1, 2, 3],
    result = Array.from({ length: 3 * array.length }, (_, i) => array[i % array.length]);

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • IMO, this one is the most efficient and seems to equate to a malloc followed by a single loop over the array elements. Other solutions seem to involve multiple loops over the array elements. – Max Waterman Sep 07 '20 at 03:45
2

One quick way is joining the array, repeating it using string.repeat(), then splitting it and finally using ES6 Spreads

The other answer are probably better. This is just a simpel one-liner.

let arr = [1, 2, 3];
let res = [...arr.join("").repeat(3).split("").map(Number)];

console.log(res);
NullDev
  • 6,739
  • 4
  • 30
  • 54
1

Plain and Simple:

    var n=4; //times //put 100
    var array = [1,2,3];
    var newarray = [];
    while(n--){ var newarray = newarray.concat(array); }
    alert(newarray);
Hackinet
  • 3,252
  • 1
  • 10
  • 22
-1

Try 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.