连接N个数组的最有效方法是什么?

时间:2011-02-22 15:20:37

标签: javascript arrays

在JavaScript中连接N个对象数组的最有效方法是什么?

数组是可变的,结果可以存储在其中一个输入数组中。

23 个答案:

答案 0 :(得分:275)

如果要连接两个以上的数组,concat()是方便和可能性能的方法。

var a = [1, 2], b = ["x", "y"], c = [true, false];
var d = a.concat(b, c);
console.log(d); // [1, 2, "x", "y", true, false];

为了连接两个数组,可以使用push接受包含要添加到数组的元素的多个参数的事实来将一个数组中的元素添加到另一个数组的末尾而不生成新数组。使用slice(),也可以使用concat()代替there appears to be no performance advantage from doing this

var a = [1, 2], b = ["x", "y"];
a.push.apply(a, b);
console.log(a); // [1, 2, "x", "y"];

在ECMAScript 2015及更高版本中,这可以进一步减少到

a.push(...b)

但是,似乎对于大型数组(大约100,000个成员或更多),将一组元素传递给push(使用apply()或ECMAScript 2015传播运算符)的技术可能会失败。对于这样的数组,使用循环是一种更好的方法。有关详细信息,请参阅https://stackoverflow.com/a/17368101/96100

答案 1 :(得分:147)

[].concat.apply([], [array1, array2, ...])

编辑:效率证明:http://jsperf.com/multi-array-concat/7

edit2 :Tim Supinie在评论中提到这可能导致解释器超出调用堆栈大小。这可能取决于js引擎,但我至少还得到了“Chrome上的最大调用堆栈大小”。测试用例:[].concat.apply([], Array(300000).fill().map(_=>[1,2,3]))。 (我也使用当前接受的答案得到了同样的错误,因此人们期待这样的用例或为其他人建立一个库,无论您选择哪种解决方案,都可能需要进行特殊测试。)

答案 2 :(得分:25)

concat()方法用于连接两个或多个数组。它不会更改现有数组,只会返回已连接数组的副本。

array1 = array1.concat(array2, array3, array4, ..., arrayN);

答案 3 :(得分:25)

对于使用ES2015(ES6)的人

您现在可以使用Spread语法来连接数组:

const arr1 = [0, 1, 2],
      arr2 = [3, 4, 5];

const result1 = [...arr1, ...arr2]; // -> [0, 1, 2, 3, 4, 5]

// or...

const result2 = [...arr2, ...arr1]; // -> [3, 4, 5, 0, 1, 2]

答案 4 :(得分:20)

使用Array.prototype.concat.apply来处理多个数组'级联:

var resultArray = Array.prototype.concat.apply([], arrayOfArraysToConcat);

示例:

var a1 = [1, 2, 3],
    a2 = [4, 5],
    a3 = [6, 7, 8, 9];
Array.prototype.concat.apply([], [a1, a2, a3]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

答案 5 :(得分:12)

如果您正在通过map / filter / sort等管道结果并且想要连接数组数组,那么可以使用reduce

let sorted_nums = ['1,3', '4,2']
  .map(item => item.split(','))   // [['1', '3'], ['4', '2']]
  .reduce((a, b) => a.concat(b))  // ['1', '3', '4', '2']
  .sort()                         // ['1', '2', '3', '4']

答案 6 :(得分:10)

对于多个阵列和ES6的数组,请使用

Array.prototype.concat(...arr);

例如:

const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = Array.prototype.concat(...arr);
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

答案 7 :(得分:7)

现在我们可以使用import java.awt.event.*; import java.awt.*; import javax.swing.*; public class CarView extends JFrame { private JLabel yearModel,make,speed, color; //labels for; yearModel, make, and speed private JTextField yearModelText, makeText, speedText; //Text field for yearMake, make, private JButton accelerate, brake; //botton for accelerate, brake //Constructor public CarView(Car car) { //setting name/header for window super("Car Simulation View Window"); //Setting frame size of window setSize(400, 250); //Specifying what will happen when botton clicked setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Setting the window to non-adjustable setResizable(false); //Adding components to panel addComponents(car); //Setting frame to visible setVisible(true); } //Adding components private void addComponents(Car car) { //Create panel to hold UI compoenents JPanel panel = new JPanel(); //Setting title of JPanel as CarUI panel.setBorder(BorderFactory.createTitledBorder("CarUI")); //Setting the panel layout panel.setLayout(new GridBagLayout()); //Creating the year label yearModel = new JLabel("Year"); //Adding the year label (0by0colum) addToPanel(panel, yearModel, 0, 0); //Creating the year text yearModelText = new JTextField(car.getYearModel() + ""); //Making yearModelText to only readible yearModelText.setEditable(false); //Adding the yearText (0by2colum) addToPanel(panel, yearModelText, 0, 2); //Creating make label make = new JLabel("Make"); //Adding the make label (1by0colum) addToPanel(panel, make, 1, 0); //Creating the make text makeText = new JTextField(car.getMake()); //Making make text to onely readeble makeText.setEditable(false); //Adding makeText to panel (1by2colum) addToPanel(panel, makeText, 1, 2); //Creating the speed label speed = new JLabel("Speed"); //Adding the speed label addToPanel(panel, speed, 2, 0); speedText = new JTextField(car.getSpeed()); speedText.setEditable(false); addToPanel(panel, speedText, 2, 2); //Creating the accelerate button accelerate = new JButton("Accelerate"); //Adding the accelerate button to a 4by0colum addToPanel(panel, accelerate, 4, 0); //Adding the action listener to the accelerate button accelerate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //accelerating the car car.accelerate(); } }); //Creating the brake button brake = new JButton("Brake"); //Adding the brake button at 4 row and 2 column addToPanel(panel, brake, 4, 2); //Adding the action listener to the acceleration button brake.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //Apply brakes to the car car.brake(); } }); // Add panel to the frame add(panel); } //Ading components to panel private void addToPanel(JPanel panel, Component comp, int row, int column) { //Seting Constrain for layaout GridBagConstraints layoutConstraint = new GridBagConstraints(); layoutConstraint.fill = GridBagConstraints.BOTH; layoutConstraint.anchor = GridBagConstraints.NORTH; //Setting constrain sizes in the folowing lines layoutConstraint.gridwidth = 2; layoutConstraint.weightx = 1; layoutConstraint.weighty = 0; layoutConstraint.ipady = 10; layoutConstraint.gridx = column; layoutConstraint.gridy = row; //Adding the constrains to panel panel.add(comp, layoutConstraint); } public static void main(String[] args) { //New Car object that will be displayed Car c = new Car("Toyota", 1995); new CarView(c); } } ES6组合多个数组。 不要使用Spread来连接数组,而是尝试使用扩展语法将多个数组合并为一个扁平数组。 例如:

concat()

答案 8 :(得分:4)

使用concat函数轻松实现:

var a = [1,2,3];
var b = [2,3,4];
a = a.concat(b);
>> [1,2,3,2,3,4]

答案 9 :(得分:3)

您可以使用jsperf.com网站来比较效果。这是指向concat的链接。

在:

之间添加了比较
var c = a.concat(b);

var c = [];
for (i = 0; i < a.length; i++) {
    c.push(a[i]);
}
for (j = 0; j < b.length; j++) {
    c.push(b[j]);
}

第二个是铬的慢近10倍。

答案 10 :(得分:2)

这是一个可以连接多个数组的函数

function concatNarrays(args) {
    args = Array.prototype.slice.call(arguments);
    var newArr = args.reduce( function(prev, next) {
       return prev.concat(next) ;
    });

    return newArr;
}

示例 -

console.log(concatNarrays([1, 2, 3], [5, 2, 1, 4], [2,8,9]));

将输出

[1,2,3,5,2,1,4,2,8,9]

答案 11 :(得分:2)

其中'n'是一些数组,可能是一个数组数组。 。

var answer = _.reduce(n,function(a,b){return a.concat(b)})

答案 12 :(得分:2)

如果您有数组数组并希望将元素连接成一个数组,请尝试以下代码(需要ES2015):

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = [];
for (let arr of arrOfArr) {
    newArr.push(...arr);
}

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

或者如果你正在进行函数式编程

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = arrOfArr.reduce((result,current)=>{
    result.push(...current);
    return result;
});

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

使用ES5语法甚至更好,没有扩展运算符

var arrOfArr = [[1,2,3,4],[5,6,7,8]];
var newArr = arrOfArr.reduce((result,current)=>{
    return result.concat(current);
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

如果您不知道否,这种方式很方便。代码时的数组。

答案 13 :(得分:2)

像这样解决。

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));

答案 14 :(得分:2)

用ES6缩小。

new Set([].concat(...Array));

这可以 concat 唯一多个数组;

Demo on codepen

答案 15 :(得分:1)

如果只有两个数组要连接,并且你实际上需要追加一个数组而不是创建一个数组,那么推送或循环是可行的方法。

基准:https://jsperf.com/concat-small-arrays-vs-push-vs-loop/

答案 16 :(得分:1)

你可以用这个 -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];

let array1d = array2d.reduce((merged, block) => {
                          merged.push(...block); 
                          return merged; 
                     }, []);

console.log(array1d); // [1, 2, 3, 5, 4, 7, 8]

或者从上面的一个答案中我喜欢这个 -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log([].concat(...array2d)); // [1, 2, 3, 5, 4, 7, 8]

或者我发现的这个 -

let array2d = [[1, 2, 3], [5, 4], [7, 8]];
console.log(array2d.join().split(',').map(Number); // [1, 2, 3, 5, 4, 7, 8]

答案 17 :(得分:0)

试试这个:

i=new Array("aaaa", "bbbb");
j=new Array("cccc", "dddd");

i=i.concat(j);

答案 18 :(得分:0)

如果N个数组是从数据库中获得的,并且未进行硬编码,那么我将使用ES6这样做

let get_fruits = [...get_fruits , ...DBContent.fruit];

答案 19 :(得分:0)

使用推入合并数组:

const array1 = [2, 7, 4];
const array2 = [3, 5,9];
array1.push(...array2);
console.log(array1)

使用 Concat Spread运算符:

const array1 = [1,2];
const array2 = [3,4];

// Method 1: Concat 
const combined1 = [].concat(array1, array2);

// Method 2: Spread
const combined2 = [...array1, ...array2];

console.log(combined1);
console.log(combined2);

答案 20 :(得分:0)

在不同的JS引擎中,正确答案似乎有所不同。这是我从the test suite linked in ninjagecko's answer获得的结果:

  • [].concat.apply在Windows和Android的Chrome 83中最快,其次是reduce(慢56%);
  • 循环播放的concat在Mac的Safari 13中最快,其次是reduce(慢13%);
  • reduce在iOS上的Safari 12中最快,其次是循环的concat(慢40%);
  • elementwise push在Windows的Firefox 70中最快,其次是[].concat.apply(慢30%)。

答案 21 :(得分:0)

最快的 10 倍是遍历数组,就好像它们是一个一样,而不实际加入它们(如果你能帮忙的话)。

我很惊讶 concat 比 push 稍微快一点,除非测试不公平。

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's'];
const arr3 = ['t', 'u', 'v', 'w'];
const arr4 = ['x', 'y', 'z'];

let start;

// Not joining but iterating over all arrays - fastest
// at about 0.06ms
start = performance.now()

const joined = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  let i = 0;
  while (joined.length) {
    // console.log(joined[0][i]);
    if (i < joined[0].length - 1) i++;
    else {
      joined.shift()
      i = 0;
    }
  }
}

console.log(performance.now() - start);

// Concating (0.51ms).
start = performance.now()

for (let j = 0; j < 1000; j++) {
  const a = [].concat(arr1, arr2, arr3, arr4);
}

console.log(performance.now() - start);

// Pushing on to an array (mutating). Slowest (0.77ms)
start = performance.now()

const joined2 = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  const arr = [];
  for (let i = 0; i < joined2.length; i++) {
    Array.prototype.push.apply(arr, joined2[i])
  }
}

console.log(performance.now() - start);

如果你抽象它,你可以在不加入更干净的情况下进行迭代,而且它的速度仍然是原来的两倍:

const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['j', 'k', 'l', 'i', 'm', 'n', 'o', 'p', 'q', 'r', 's'];
const arr3 = ['t', 'u', 'v', 'w'];
const arr4 = ['x', 'y', 'z'];

function iterateArrays(arrays, onEach) {
  let i = 0;
  while (joined.length) {
    onEach(joined[0][i]);
    if (i < joined[0].length - 1) i++;
    else {
      joined.shift();
      i = 0;
    }
  }
}

// About 0.23ms.
let start = performance.now()

const joined = [arr1, arr2, arr3, arr4];

for (let j = 0; j < 1000; j++) {
  iterateArrays(joined, item => {
    //console.log(item);
  });
}

console.log(performance.now() - start);

答案 22 :(得分:0)

您可以查看此博客,这里比较了 push() 和 concat() 的性能。还定制了在特定场景下表现更好的自定义函数。

https://dev.to/uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki