Whats the easiest way (with "native" javascript) to duplicate every element in a javascript array?
The order matters.
For example:
a = [2, 3, 1, 4]
// do something with a
a
// a is now [2, 2, 3, 3, 1, 1, 4, 4]
Whats the easiest way (with "native" javascript) to duplicate every element in a javascript array?
The order matters.
For example:
a = [2, 3, 1, 4]
// do something with a
a
// a is now [2, 2, 3, 3, 1, 1, 4, 4]
I came up with something similar to tymeJV's answer
[2, 3, 1, 4].reduce(function (res, current, index, array) {
return res.concat([current, current]);
}, []);
Basically you can use flatMap
in ES19
a = [1, 2, 3, 4];
a.flatMap(i => [i,i]); // [1, 1, 2, 2, 3, 3, 4, 4]
Also you can customize the repetitions number like this:
a = [1, 2, 3, 4];
const dublicateItems = (arr, numberOfRepetitions) =>
arr.flatMap(i => Array.from({ length: numberOfRepetitions }).fill(i));
dublicateItems(a, 3);
My reply to the comment below by @user120242 why so complicated? a.flatMap(i => Array(n).fill(i)) find it here
Basically:
a = [2, 3, 1, 4];
b=[];
for(var i = 0; i< a.length;++i){
b.push(a[i]);
b.push(a[i]);
}
a=b;
I came across this issue in my application, so I created this function:
function duplicateElements(array, times) {
return array.reduce((res, current) => {
return res.concat(Array(times).fill(current));
}, []);
}
To use it, simple pass the array, and the number of times you want the elements to be duplicated:
duplicateElements([2, 3, 1, 4], 2);
// returns: [2, 2, 3, 3, 1, 1, 4, 4]
I suppose you could do:
var duplicated = a.map(function(item) {
return [item, item];
}).reduce(function(a, b) { return a.concat(b) });
//duplicated: [2, 2, 3, 3, 1, 1, 4, 4]
ES6 way of life (based on axelduch's answer)
const arr = [2, 3, 1, 4].reduce((res, current) => [...res, current, current], []);
console.log(arr);
A very basic snippet by just using loops and push.
It's dynamic function, So you can specify duplicator to duplicate value number of times.
Function name duplicate
Syntax: duplicate (array, duplicator)
How it works: function takes two parameter array and duplicator, It build new array based on duplicator and return newly built array.
Snippet
function duplicate(array, duplicator){
var buildArray = [];
for(i=0; i<array.length; i++){
for(j=0; j<duplicator; j++){
buildArray.push(array[i]);
}
}
return buildArray;
}
Usage
var a = [2, 3, 1, 4];
var result = duplicate(a, 2);
console.log(result);
Change duplicator value according to your requirement to get desired output.
Reference:
Just splice a little bit.
var a = [2, 3, 1, 4],
i = a.length;
while (i--) {
a.splice(i, 0, a[i]);
}
document.write('<pre>' + JSON.stringify(a, 0, 4) + '</pre>');
These functions may help see .sort(), .concat()
function duplicate(arr) {
return arr.concat(arr).sort()
}
console.log(duplicate([1,2,3,4,5]))
how 'bout that?
for (i=a.length-1;i>=0;i--)a.splice(i,0,a[i]);
iterating backwards is undervalued, in this case it keeps the index intact ;)
0/2 = 0 = 0 |0 = 0
1/2 = 0.5 = 0.5|0 = 0
2/2 = 1 = 1 |0 = 1
3/2 = 1.5 = 1.5|0 = 1
4/2 = 2 = 2 |0 = 2
5/2 = 2.5 = 2.5|0 = 2
6/2 = 3 = 3 |0 = 3
7/2 = 3.5 = 3.5|0 = 3
Treat |0
as Math.floor
In code this could look like this:
for (let i = 0; i < a.length * 2; i++) {
a[i] = a[i / 2 | 0]
}
Because immutability is preferable, one could do something like this:
function repeatItems(a, n) {
const b = new Array(a.length * n)
for (let i = 0; i < b.length; i++) {
b[i] = a[i / n | 0]
}
return b
}
Unreadable ES6 spaghetti code:
const repeatItems = (a, n) => Array.from(Array(a.length * n), (_, i) => a[i / n | 0])
Lot of ways to add items to an array as seen above. I have compared it and you can view the performance by yourself in the console. Whatever is timed goes between the two "console.time"
console.clear();
function loopMyArray(){
var loopArray = new Array(10000);
for(var i = 0; i < loopArray.length; i++){
loopArray[i] = i+1;
}
console.log(loopArray);
}
console.time('loopMyArray');
loopMyArray();
console.timeEnd('loopMyArray');
function fillArray(){
let x = 0;
let filledArray = new Array(10000).fill(null).map(()=> ++x);
console.log(filledArray);
}
console.time('fillArray');
fillArray();
console.timeEnd('fillArray');
function keyMyArray(){
let fromKeyArray = Array.from(Array(10000).keys());
console.log(fromKeyArray);
}
console.time('keyMyArray');
keyMyArray();
console.timeEnd('keyMyArray');
function spreadKeysArray(){
let spreadArray = [...Array(10000).keys()];
console.log(spreadArray);
}
console.time('spreadKeysArray');
spreadKeysArray();
console.timeEnd('spreadKeysArray');
console.log(' Start from 1');
function mapKeyArray(){
//let mapArray = ([...Array(1000).keys()].map(x => x++)); //increment after return
let mapArray = [...Array(10000).keys()].map(x => ++x);
console.log(mapArray);
}
console.time('mapKeyArray');
mapKeyArray();
console.timeEnd('mapKeyArray');
function sliceKeyArray(){
let sliceFirstElementArray = [...Array(10000+1).keys()].slice(1);
console.log(sliceFirstElementArray);
}
console.time('sliceKeyArray');
sliceKeyArray();
console.timeEnd('sliceKeyArray');
function calcFromLength(){
let fromLengthArray = Array.from({length: 10000}, (v, k) => k+1);
console.log(fromLengthArray);
}
console.time('calcFromLength');
calcFromLength();
console.timeEnd('calcFromLength');
console.log('======== add a double for every item ========');
function loopDoubleArray(){
var first5000Array = [...Array(5000+1).keys()].slice(1);
var double5000Array =[];
for(var i = 0; i< first500Array.length;++i){
double5000Array.push(first5000Array[i]);
double5000Array.push(first5000Array[i]);
}
console.log(double5000Array);
}
console.time('loopDoubleArray');
loopDoubleArray(); // Whatever is timed goes between the two "console.time"
console.timeEnd('loopDoubleArray');
function mapDoubleArray(){
// adding 1,1,2,2,3,3 etc
let doubleArray = [...Array(10000).keys()].map(x => Math.floor(++x/2) + x%2);
console.log(doubleArray);
}
console.time('mapDoubleArray');
mapDoubleArray();
console.timeEnd('mapDoubleArray');
function fromDoubleArray(){
let fromDoubleArray = Array.from({length: 10000}, (v, x) => Math.floor(++x/2) + x%2);
console.log(fromDoubleArray);
}
console.time('fromDoubleArray');
fromDoubleArray(); // Whatever is timed goes between the two "console.time"
console.timeEnd('fromDoubleArray');
function doubleSpreadArray(){
let keyArray = [...Array(500+1).keys()].slice(1);
let doubleSpreadArray = [...keyArray,...keyArray];
console.log(doubleSpreadArray);
}
console.time('doubleSpreadArray');
doubleSpreadArray(); // Whatever is timed goes between the two "console.time"
console.timeEnd('doubleSpreadArray');
function reduceDoubleArray(){
let reduceDoubleArray = Array.from({length: 5000}, (v, k) => k+1).reduce((m,i) => m.concat([i,i]), []);
console.log(reduceDoubleArray);
}
console.time('reduceDoubleArray');
reduceDoubleArray(); // Whatever is timed goes between the two "console.time"
console.timeEnd('reduceDoubleArray');
I compared some speeds and it looks as if there are not so many differences. The speed(in ms for 10000 items) of calculation between map
, slice
and from
are not so different (slice one seems a bit better). Using reduce in the calculation for double items array is way more slower then the rest of methods
| mapMyArray | 5,342041016 | 5,21484375 | 8,424804688 | 5,516113281 |
| sliceKeyArray | 5,221191406 | 4,854248047 | 6,069091797 | 4,940185547 |
| calcFromLength | 6,156005859 | 5,988037109 | 6,031982422 | 6,739990234 |