4

I am trying to populate items of an array with same items and order.

As an example, I have an array like this, with two string elements.

const myArr = ['A','B'];

What I'm trying to do is something like that. I need to populate items 10 times or more. I'm thinking of a for loop but maybe there are more efficient alternatives.

const myArr2 = ['A','B','A','B','A','B','A','B','A','B'];

How can I achieve this with Vanilla JS ?

Çetin
  • 117
  • 2
  • 6
  • I would be interested to know if there is a way to do it without a loop. I would have done a loop to achieve that. – MrJami Mar 11 '21 at 17:12
  • @MrJami It's really strange though. I'm making a marquee animation. By default, there are almost 100 lines of html and looks very unprofessional. In my mind, creating array and populating it before html injection would be a good shortcut. Could you please share your approach with loop? – Çetin Mar 11 '21 at 17:16
  • You could use array fill method to populate the same values 'n' no: of times as per your requirement. Example - let filledArray = new Array(10).fill('A'); – Zam Abdul Vahid Mar 11 '21 at 17:19
  • There are several ways to do this in some way, but sadly, i still don't know an equivalent of the low level `TypedArray.prototype.set` for normal arrays. Therefore, something like `Array.from({ length: 10 }, () => ['A', 'B']).flat()` is the best i can think of, or similar ways, that result in useless intermediary arrays, and pray the function inliner works properly – ASDFGerte Mar 11 '21 at 17:20

7 Answers7

3

You could take a standard approach with an array constructor, the length, a filling and flattening.

const
    pattern = ['A','B'],
    times = 5,
    result = Array(times).fill(pattern).flat();

console.log(...result);
    
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

With a simple for loop:

const myArr = ['A','B'];

const times = 10;

let newArr = [];
for (let i=0;i<times;i++){
  newArr = newArr.concat(myArr);
}

console.log(newArr)

Oneliner:

const myArr = ['A','B'];
const times = 10;
const len = myArr.length;

const newArr = Array(len*times).fill(0).map( (x,i) => myArr[i%len]);

console.log(newArr)
malarres
  • 2,941
  • 1
  • 21
  • 35
  • Thank you, it's a descent approach, I've achived it like this. ``` const myArr = ['A','B']; const secondArr = []; for(let i = 0; i<20; i++){ myArr.forEach(item =>secondArr.push(item)) } ``` – Çetin Mar 11 '21 at 17:24
2

If you're not opposed to loops, you could use the spread syntax to push the contents of your array a number of times.

const myArr = ['A', 'B'];

let myArr2 = [];
for (let i = 0; i < 5; i++) {
  myArr2.push(...myArr);
}

console.log(myArr2);

If you don't like loops, Array.map could work.

const myArr = ['A', 'B'];

let myArr2 = Array.from({ length: 10 })
                  .map((x, i) => x = myArr[i % 2]); 

console.log(myArr2);
D M
  • 5,769
  • 4
  • 12
  • 27
  • I've achived this with an old school loop, I was wondering if it's possible in other ways. Thank you for sharing your mapping approach it looks perfect. – Çetin Mar 11 '21 at 17:26
1

As requested, this would be my approach with loop:

I would use a negative while loop (explanation why) You can also check the methods out to see which method is the fastest one. I made a test here comparing the push method in a for loop and Array.map and also the negative while loop. On my browser the negative while loop was the fastest. If you want to have much more duplicates (e.g. 1000 duplicates) then the difference of the methods will be even larger (benchmark test for 1024 array length and various methods).

It seems that chromium based browsers (Opera, Edge, google chrome) get the fastest results with a negative while loop and for firefox the array.from map function delivers the fastest results.

let myArray = ['A', 'B'];

let k = 10; //array.length^k = new array length

while (--k){
    myArray.push(...myArray);
}

console.log(myArray);
MrJami
  • 685
  • 4
  • 16
  • 1
    Thank you for sharing, this is the first time I'm seeing a negative while loop in action. – Çetin Mar 11 '21 at 17:27
  • 1
    @Çetin you can also test this in a benchmark https://jsben.ch/MBG1a I also added the answer above to the benchmark, the negative loop is even duplicating more and it still is the fastest method – MrJami Mar 11 '21 at 17:33
  • Now I see... your implemention is WRONG according to what OP asked. It creates arrays with length raised to the power of 2. If I want to replicate 19 times, how would I do? – testing_22 Mar 11 '21 at 19:37
  • @testing_22 he asked me to show him my approach :) that's what I did ^^ – MrJami Mar 12 '21 at 01:24
1

You can simply use push and recursion WITHOUT loops

const newArr = []    
const myArr = ['A','B']

const replicate = n => 
(n === 0 ? [] : newArr.push(...myArr) & replicate(n-1));

replicate(3)
console.log(newArr)
testing_22
  • 2,340
  • 1
  • 12
  • 28
  • This method is the slowest method on any browser, it is 80+ times slower than other methods (while duplicating over 500 times) – MrJami Mar 11 '21 at 18:12
1

Using Array.prototype.join("") and String.prototype.repeat().

const
    data = ['A','B'],
    result = Array.from(data.join("").repeat(5));

console.log(result);
    
-1

Try

myArr.push('A');

foreach element you want to add.