Repeat an array with multiple elements multiple times in JavaScript

末鹿安然 提交于 2019-11-29 05:33:11

No need for any library, you can use Array.from to create an array of arrays you want repeated, and then flatten using [].concat and spread:

const makeRepeated = (arr, repeats) =>
  [].concat(...Array.from({ length: repeats }, () => arr));
  
console.log(makeRepeated([1, 2, 3], 2));

On newer browsers, you can use Array.prototype.flat instead of [].concat(...:

const makeRepeated = (arr, repeats) =>
  Array.from({ length: repeats }, () => arr).flat();
  
console.log(makeRepeated([1, 2, 3], 2));

You can use the Array constructor along with its fill method to fill it a number of times of the array you want to repeat, then concat them (the subarrays) into a single array:

const repeatedArray = [].concat(...Array(num).fill(arr));

Note: On older browsers (pre-ES6), you can use Function#apply to mimic the rest syntax above (concat will be called with each of the sub arrays passed to it as argument):

var repeatedArray = [].concat.apply([], Array(num).fill(arr));

Example:

const arrayToRepeat = [1, 2, 3];
const numberOfRepeats = 3;

const repeatedArray = [].concat(...Array(numberOfRepeats).fill(arrayToRepeat));

console.log(repeatedArray);

Recursive alternative:

const repeat = (a, n) => n-- ? a.concat(repeat(a, n)) : [];

console.log( repeat([1, 2], 3) )

My first idea would be creating a function like this

let repeat = (array, numberOfTimes) => Array(numberOfTimes).fill(array).reduce((a, b) => [...a, ...b], [])
console.log(repeat(["a", "b", "c"], 3))

using the fill method and reduce

Ideally, instead of using reduce you could use flatten but there's yet no support in browsers

Unfortunately, it is not possible natively in JS (Also operator overloading is not possible, so we can not use something like Array.prototype.__mul__), but we can create an Array with the proper target length, fill with placeholders, then re-map the values:

const seqFill = (filler, multiplier) => 
  Array(filler.length * multiplier)
  .fill(1)
  .map(
    (_, i) => filler[i % filler.length]
  );

console.log(seqFill([1,2,3], 3));
console.log(seqFill(['a','b','c', 'd'], 5));

Or another way by hooking into the Array prototype, you could use the syntax of Array#seqFill(multiplier), this is probably the closest you can get to ruby syntax (rb can do basically everything with operator overloading, but JS can't):

Object.defineProperty(Array.prototype, 'seqFill', {
  enumerable: false,
  value: function(multiplier) {
    return Array(this.length * multiplier).fill(1).map((_, i) => this[i % this.length]);
  }
});

console.log([1,2,3].seqFill(3));

Apart from the obvious [].concat + Array.from({length: 3}, …)/fill() solution, using generators will lead to elegant code:

function* concat(iterable) {
    for (const x of iterable)
        for (const y of x)
            yield y;
}
function* repeat(n, x) {
    while (n-- > 0)
        yield x;
}

const repeatedArray = Array.from(concat(repeat(3, [1, 2, 3])));

You can also shorten it to

function* concatRepeat(n, x) {
    while (n-- > 0)
        yield* x;
}

const repeatedArray = Array.from(concatRepeat(3, [1, 2, 3]));

Though other methods works simply, these too.

Array.fill() and Array.from() in previous methods will not work in IE. MDN Docs for Reference

Mehtod 1 : Loop and push (Array.prototype.push) the same into the array.

function mutateArray(arr,n)
{
    var temp = [];
    while(n--) Array.prototype.push.apply(temp,arr);
    return temp;
}
var a = [1,2,3,4,5];
console.log(mutateArray(a,3));

Method 2: Join the array elements and String.repeat() to mutate the string and return the split string.

Note: The repeat method is not supported yet in IE and Android webviews.

function mutateArray(arr,n)
{
    var arr = (arr.join("$")+"$").repeat(n).split("$");
    arr.pop(); //To remove the last empty element
    return arr;
}
var a = [1,2,3,4,5];
console.log(mutateArray(a,3));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!