如何在JavaScript数组中复制元素?

41

如何使用“原生”JavaScript最简单地复制JavaScript数组中的每个元素?

顺序很重要。

例如:

a = [2, 3, 1, 4]
// do something with a
a
// a is now [2, 2, 3, 3, 1, 1, 4, 4]

不推荐使用,但正则表达式也可以被使用。a = a.join(',').replace(/(\d+)/g, "$1,$1").split(',').map(Number); - Tushar
@Tushar 不错的想法。然而,正如你所假设的那样,我正在寻找一个通用解决方案,它也适用于可能甚至包含逗号的字符串数组... - Jan Rüegg
3
这个问题的最佳答案似乎是复杂度代码高尔夫游戏。不要使用reduce函数,因为它可能会让意图变得不清晰。有时候for循环才是正确的答案,抱歉。 - Nathan Cooper
12个回答

-1
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

|0视为Math.floor


在代码中,它可能看起来像这样:

for (let i = 0; i < a.length * 2; i++) {
  a[i] = a[i / 2 | 0]
}

因为不可变性更可取,所以可以这样做:

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
}

难以阅读的ES6代码:

const repeatItems = (a, n) => Array.from(Array(a.length * n), (_, i) => a[i / n | 0])

-2

有很多方法可以像上面看到的那样向数组中添加项目。我已经进行了比较,您可以在控制台中自行查看性能。 无论计时什么都位于两个“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');


我比较了一些速度,似乎没有太多的差别。在处理1万项数据时,使用mapslicefrom计算的速度并不相差太大(其中slice稍微优一些)。然而,在处理双倍项目数组时,使用reduce计算的速度要慢得多。
| 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 |

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接