将多个元素放入JavaScript数组

5

JavaScript 中,我通过传统方式填充 数组 元素,例如:

myArray[12] = 123;
myArray[13] = 432;
myArray[14] = 233;
myArray[15] = 98;

有没有办法只用一个命令更快地完成这个操作?

例如,将数字[123, 432, 233, 98]放入myArray[12-15]中...有什么方法可以实现吗?不是一个一个添加。


如何优化此类场景:

newArray[12] = oldArray[30];
newArray[13] = oldArray[31];
newArray[14] = oldArray[32];
newArray[15] = oldArray[33];

当需要将一个数组中相邻的n个元素(在上面的例子中为4个)移动到另一个数组中时,应该怎么办?

请给出建议。


这些值从哪里来的? - Robert
6个回答

10
var myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
               12, 13, 14, 15, 16, 17, 18, 19, 20];
myArray.splice(12, 4, 123, 432, 233, 98);

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
//  123, 432, 233, 98, 16, 17, 18, 19, 20]
splice的第一个参数是要开始操作的索引,第二个参数是要删除的元素数量,剩余的参数是要插入的元素。如果插入的元素数量与删除的数量相同,则相当于对它们进行替换。
如果您想从另一个数组中获取要插入的元素,可以尝试以下方法,但这并不太简洁:
var oldArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
               12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
               22, 23, 24, 25, 26, 27, 28, 29, 123, 
               432, 233, 98, 34, 35]
var newArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
               12, 13, 14, 15, 16, 17, 18, 19, 20];

[].splice.apply(newArray, [12, 4].concat(oldArray.slice(30, 30 + 4)));

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
// 123, 432, 233, 98, 16, 17, 18, 19, 20]

这种方法可能不如PointedEars的建议高效,但它相当简单,适用于许多情况。


4

最新方法:使用 Spread 和 Splice

这是最新和最简单的方法。

使用...(展开)运算符与先前示例中使用的splice方法一起使用。

这将从索引12开始删除4个元素,然后将您所需的数组插入到12到15的位置。

尝试示例代码

const myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
               12, 13, 14, 15, 16, 17, 18, 19, 20];

console.log('Before:', JSON.stringify(myArray));

myArray.splice(12, 4, ...[123, 432, 233, 98]);

console.log('After: ', JSON.stringify(myArray));

更多参考资料:ECMAScript(ECMA-262)


任何使用扩展函数参数的方法都会遇到一个有趣的缺点——意想不到的堆栈溢出错误,因为JavaScript通过堆栈传递参数。对于 arr.splice(1, 2, ...[ /* a million items */ ]),您将遇到堆栈溢出问题。 - Gershom Maes

4
你能做到的最接近的方法是使用 splice 来设置输入位置。
第一个参数是开始索引,第二个参数是要删除的项目数,下一个参数是值....
这是我在控制台上玩耍时得到的一些输出。
myArray = new Array(15)
myArray.splice(12, 4, 123, 432, 223, 98)
myArray.forEach(function(v, i){console.log(v, i)})
123 12
432 13
223 14
98 15
undefined
myArray[12]
123
myArray[13]
432
myArray[14]
223
myArray[15]
98

当然,这样有几个缺点:您无法传递要插入的值数组,该数组需要足够大(即,除非数组至少为12,否则无法在索引12处插入)。对于在一个数组中的一组索引中传输值以在另一个数组的一组索引中插入值,我认为您需要使用循环。splice以单独的方式添加值,而不是作为数组。当然,您可以编写一个带有循环的单个方法,并重复使用它。

好主意,但是 Array.prototype.splice()插入元素,而不是替换现有的元素。为了解决这个问题,您需要删除与插入相同数量的元素。我认为在这里最好的解决方案是使用循环,但如果ECMAScript实现像Python一样支持切片替换就更好了。也许在Harmony(ES 6)中会有这个功能。 - PointedEars
你刚刚做了,但现在没戏了,你必须要循环。 - hvgotcodes
SOL = 没有运气了。就像“如果你不用循环,你就没有运气了,抱歉”。 - hvgotcodes
我明白了。但是,你可以不使用循环来完成它:var items = [123, 432, 223, 98]; myArray.splice.apply(myArray, [12, items.length].concat(items));。问题是,你想这样做吗? 它比普通的、可能是通用的循环要贵两倍以上。我甚至没有谈论内存问题。请参见我的答案。 - PointedEars

2
Array.prototype.push()Array.prototype.splice()是很好的想法,但push()总是将元素添加到数组的末尾(即从由length属性指定的索引开始),而splice()要求在插入之前先删除与插入数量相同的元素(这比实际需要的操作费用高出一倍)。
因此,你应该使用一个循环:
 for (var i = 12; i < 16; ++i)
 {
   _new[i] = old[i + 18];
 }

(new是一个关键字,因此被保留;你的示例代码无法执行。我在这里使用了_new来解决这个问题。)

这可以被概括为:

function putValues(array1, array2, start1, start2, num)
{
  if (typeof start1 == "undefined") start1 = 0;
  if (typeof start2 == "undefined") start2 = 0;
  var max = (typeof num == "undefined") ? array2.length : start2 + num;

  for (var i = start1, j = start2; j < max; ++i, ++j)
  {
    array1[i] = array2[j];
  }
}

putValues(newArray, oldArray, 12, 30, 4);

更复杂的概括也是可以想象的,例如传递一个或两个索引数组,这样索引就不必连续。

(不要把这个方法变成Array.prototype的方法,除非你想在稀疏数组上以无序方式高效地使用for-in进行迭代时使用Object.prototype.hasOwnProperty()。)

下次尝试先做点什么


splice不需要你删除任何特定数量的元素。 如果您想以这种方式替换某个元素集,请先移除相应数量。 但这似乎并不是什么限制。 - Scott Sauyet
@ScottSauyet 请再次阅读问题。 - PointedEars
还要感谢那些点踩的人。仅仅因为你不理解或不喜欢一个答案,并不意味着它是错误或无用的。 - PointedEars
我重新阅读了问题并看到了“是否可能通过一个命令更快地完成这个任务?”当我看到您的代码时,可能是高效但远非简洁,我进行了点赞。然而,那是匆忙的,所以我将其删除了。 - Scott Sauyet
此外,当我回答问题时,我不认为旧数据源的添加是问题的一部分。(我可能对此有所错误。)但基本问题非常简单,也很简单地得到了解答。 - Scott Sauyet

1

1
@Blaster 向一个数组中推入另一个数组并不能得到你期望的结果。 - Mike Robinson
@Ωmega: 我还添加了 splice 函数,它允许您将项放置在指定位置。 - Blaster

1
你应该使用 .concat(),如下所示:
myArray = myArray.concat([123, 432, 233, 98])

或者使用以下方式的 .push():

myArray.push(123,432,233,98)

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