【问题标题】:JavaScript Array.concat and push workaroundJavaScript Array.concat 和推送解决方法
【发布时间】:2025-12-12 12:15:01
【问题描述】:

Array.concat 的事情总是很棘手。通常,我只想使用可变的Array.push,因为我只是在不可变数据上添加额外数据。所以,我通常这样做:

array[array.length] = newData;

我问了一个相关的问题,在这里得到了一些答案:How to store data of a functional chain

const L = (a) => {
  const m = a => (m.list ? m.list : m.list = [])
        .push(a) && m; 
  //use `concat` and refactor needed instead of `push` 
  //that is not immutable
  return m(a); // Object construction!
};

console.log(L);
console.log(L(2));
console.log(L(1)(2)(3))

一些输出:

{ [Function: m] list: [ 2 ] } 
{ [Function: m] list: [ 1, 2, 3 ] }

我觉得push应该替换为concat,但是push仍然让代码优雅,因为我们不想在这里准备另一个对象。

基本上,我想做:

arr1 = arr1.concat(arr2);

但是,有什么办法可以写

arr1[arr1.length] = arr2;

以嵌套数组结尾,并且不起作用。

【问题讨论】:

  • 你到底想做什么?请说清楚一点。
  • const m = a => (m.list ? m.list : m.list = []).push(a) && m; 那是...相当混乱的一行...
  • a.push(...b) -- 你想要这个吗?
  • @vibhor1997a -- arr1[arr1.length] = ...arr2; -- 这甚至不是一个有效的语法。
  • @31piy,你说a.push(...b) 不是一个有效的语法吗?

标签: javascript arrays concat


【解决方案1】:

您可以为未给定的m.list 分配一个带有默认数组的新数组。

const L = (a) => {
        const m = a => (m.list = (m.list || []).concat(a), m);
        return m(a);
    };

console.log(L.list);
console.log(L(2).list);
console.log(L(1)(2)(3).list);

【讨论】:

  • 谢谢,但这仍然是我通常不会做的破坏性任务。
  • 请添加你想要的。正如我理解的问题和一些 cmets,你想避免push,你想返回一个数组并且你不想将数组重新分配给list。为什么要采用返回数组的方法?
  • 请阅读最后 3 行。谢谢,我正在做函数式编程,不要使用 push 的自变异函数。
【解决方案2】:

Array.push中可以使用多个参数,所以:

var a = [];
a.push(3, 4) // a is now [3, 4]

结合 ES6 spread syntax:

var a = [1, 2];
var b = [3, 4]
a.push(...b); // a is now [1, 2, 3, 4] 

【讨论】:

  • 我基本上是想避免使用push。仅仅因为它不是返回数组的函数。这就是重点。谢谢。
  • 你要做什么,为什么要返回一个数组?
  • 简单来说就是函数式编程。
【解决方案3】:

arr1[arr1.length] 表示单个值,即索引 arr1.length 处的值。

想象一下这个数组

[ 1 , 2 , 3 , 4 ]  // arr of length 4
  ^0  ^1  ^2  ^3   // indexes

如果我们说arr1[arr1.length] = someThing

我们要求 javascript 在此处添加一些内容,并且仅在此处,在索引 4 处

[ 1 , 2 , 3 , 4 ,   ] // arr of length 4
  ^0  ^1  ^2  ^3  ^4  // add someThing in index 4

所以,如果我们想严格使用arr1[arr1.length] 添加某些内容,那么我们需要继续为每个索引执行此操作。 for each 表示任何类型的循环。例如:

// Not recommended to use
var arr1 = [1,2,3];
var arr2 = [3,4,5];

while (arr2.length){
  arr1[arr1.length] = arr2.shift();
}

console.log(arr1); // [1,2,3,3,4,5]
console.log(arr2); // []

但是,如您所见,这种方法或任何类似方法,即使经过优化,也不是正确的方法。你需要一个串联。

既然你提到了一个函数式的,它返回结果数组,你可以简单地替换初始数组并使用spread operator

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

【讨论】:

  • @Axnyff 我确实赶时间。改进了答案
  • @Adelin 再次非常感谢您。我同意你的观点,就这个问题而言,价差运算符是最好的。