【问题标题】:How to replace elements in array with elements of another array如何用另一个数组的元素替换数组中的元素
【发布时间】:2013-07-04 21:05:00
【问题描述】:

我想将某个数组中的元素从 0 元素替换为另一个长度可变的数组的元素。喜欢:

var arr = new Array(10), anotherArr = [1, 2, 3], result;
result = anotherArr.concat(arr);
result.splice(10, anotherArr.length);

有没有更好的办法?

【问题讨论】:

  • @NagaJolokia, [1, 2, 3, undefined, undefined ...]
  • 长度 === 10,对吧?
  • 而且arr总是空的,还是有时有内容?
  • 在我的情况下总是空的

标签: javascript node.js arrays concatenation array-replace


【解决方案1】:

您可以使用splice 方法将数组的一部分替换为另一个数组中的项,但您必须以特殊方式调用它,因为它希望将项作为参数,而不是数组。

splice方法需要(0, anotherArr.Length, 1, 2, 3)这样的参数,所以需要创建一个带参数的数组,并使用apply方法调用带参数的splice方法:

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr));

例子:

var arr = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
var anotherArr = [ 1, 2, 3 ];

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr));

console.log(arr);

输出:

[ 1, 2, 3, 'd', 'e', 'f', 'g', 'h', 'i', 'j']

演示:http://jsfiddle.net/Guffa/bB7Ey/

【讨论】:

  • 如果第一个数组比替换数组长,则上述解决方案不会删除最后的额外元素。这种轻微的修改将: Array.prototype.splice.apply(arr, [0, arr.length].concat(anotherArr));
  • @perilandmishap:是的,这就是重点。如果你想替换数组,你可以替换整个对象:arr = anotherArr;.
  • 在 Flux/Redux 风格的状态管理器中,您经常使用 const 并且不允许更改对对象的引用,因此仅进行重新分配不是一种选择。有这个问题很傻,但是目前javascript的状态有点傻。
【解决方案2】:

你可以只使用splice,可以在删除旧元素的同时添加新元素:

var arr = new Array(10), anotherArr = [1, 2, 3];

arr.splice.apply(arr, [0, anotherArr.length].concat(anotherArr))

如果不想修改arr 数组,可以使用返回数组浅拷贝的slice

var arr = new Array(10), anotherArr = [1, 2, 3], result = arr.slice(0);

result.splice.apply(result, [0, anotherArr.length].concat(anotherArr));

或者,您可以使用slice 切断第一个元素并在top 上添加anotherArr

result = anotherArr.concat(arr.slice(anotherArr.length));

【讨论】:

    【解决方案3】:

    我不确定这是否是一种“更好”的方式,但至少它允许您选择起始索引(而您的解决方案仅适用于从索引 0 开始)。 Here's a fiddle.

    // Clone the original array
    var result = arr.slice(0);
    // If original array is no longer needed, you can do with:
    // var result = arr;
    
    // Remove (anotherArr.length) elements starting from index 0
    // and insert the elements from anotherArr into it
    Array.prototype.splice.apply(result, [0, anotherArr.length].concat(anotherArr));
    

    (该死,这么多忍者。:-P)

    【讨论】:

      【解决方案4】:

      在这种情况下,您可以只设置数组的长度。对于更复杂的情况,请参阅@Guffa 的答案。

      var a = [1,2,3];
      a.length = 10;
      a; // [1, 2, 3, undefined x 7]
      

      【讨论】:

        【解决方案5】:

        对于任何想用另一个数组的全部内容替换一个数组的全部内容同时保留原始数组的方法的人:

        Array.prototype.replaceContents = function (array2) {
            //make a clone of the 2nd array to avoid any referential weirdness
            var newContent = array2.slice(0);
            //empty the array
            this.length = 0;
            //push in the 2nd array
            this.push.apply(this, newContent);
        };
        

        原型函数将一个数组作为参数作为新的数组内容,克隆它以避免任何奇怪的引用内容,清空原始数组,然后将传入的数组作为内容推入。这会保留原始数组和任何引用。

        现在你可以简单地这样做了:

        var arr1 = [1, 2, 3];
        var arr2 = [3, 4, 5];
        arr1.replaceContents(arr2);
        

        我知道这并不是最初的问题,但是当您在 google 中搜索时,这个问题首先出现,我认为其他人可能会觉得这很有帮助,因为这是我需要的答案。

        【讨论】:

          【解决方案6】:

          在 ES6、TypeScript、Babel 或类似的你可以这样做:

          arr1.length = 0; // Clear your array
          arr1.push(...arr2); // Push the second array using the spread opperator
          

          简单。

          【讨论】:

          • Simlpe,但是如果它是一个关联数组呢?
          【解决方案7】:

          在具有单个操作的 ES6 中,您可以这样做以将 a 的第一个 b.length 元素替换为 b 的元素:

          let a = [1,  2,  3,  4,  5]
          let b = [10, 20, 30]
          
          a.splice(0, b.length, ...b)
          
          console.log(a) // -> [10, 20, 30, 4, 5]
          

          在拼接长度中使用a.length(或Infinity替换数组的全部内容也很有用:

          let a = [1,  2,  3,  4,  5]
          let b = [10, 20, 30]
          
          a.splice(0, a.length, ...b)
          // or
          // a.splice(0, Infinity, ...b)
          
          console.log(a) // -> [10, 20, 30], which is the content of b
          

          a 数组的内容将完全替换为 b 内容。

          注意 1:在我看来,数组变异应该只用于性能关键的应用程序,例如高 FPS 动画,以避免创建新数组。通常我会创建一个保持不变性的新数组。

          注意2:如果b是一个非常大的数组,不建议使用这种方法,因为...bsplice的参数中被传播,并且数量有限制JS 函数可以接受的参数。在这种情况下,我鼓励使用另一种方法(或创建一个新数组,如果可能的话!)。

          【讨论】:

          • 只需使用a.splice(0, Infinity, ...b)。第二个参数无关紧要,只要它大于要删除的元素数。
          • 很好,但最初的问题是如何替换第一个数组的一部分。它应该是a.splice(0, b.length, ...b) - 改为测量 b 的长度。它适用于任意长度的两个数组
          • 这对于大型数组来说是 v 慢的,最终可能会出现在 Maximum recursion depth exceeced
          • @javadba 没错,对于非常大的数组,我认为您应该创建一个新数组。我相信循环时间确实克服了创造时间。 (无论如何,Maximum recursion 错误非常神秘......该代码中没有递归,我认为浏览器实现中从来没有任何递归)
          • @javadba 我添加了一个注释 2 来给出这个警告!谢谢。
          猜你喜欢
          • 1970-01-01
          • 2019-12-20
          • 1970-01-01
          • 1970-01-01
          • 2012-11-13
          • 2020-03-19
          • 2016-11-11
          • 2015-11-09
          • 2021-12-12
          相关资源
          最近更新 更多