簡體   English   中英

連接 N 個數組的最有效方法是什么?

[英]What is the most efficient way to concatenate N arrays?

在 JavaScript 中連接 N 個對象數組的最有效方法是什么?

數組是可變的,結果可以存儲在輸入數組之一中。

如果您要連接兩個以上的數組,則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()這樣做似乎沒有性能優勢

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

[].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])) (我在使用當前接受的答案時也遇到了同樣的錯誤,因此人們正在預測此類用例或為其他人構建庫,無論您選擇哪種解決方案,都可能需要進行特殊測試。)

對於使用 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]

concat()方法用於連接兩個或多個數組。 它不會更改現有數組,它只返回連接數組的副本。

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

使用 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]

對於多個數組和 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 ]

如果您正在通過 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']

像這樣解決了。

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

現在我們可以使用ES6 Spread組合多個數組。 不要使用concat()來連接數組,而是嘗試使用展開語法將多個數組合並為一個扁平數組。 例如:

var a = [1,2];
var b = [3,4];
var c = [5,6,7];
var d = [...a, ...b, ...c];
// resulting array will be like d = [1,2,3,4,5,6,7]

用 ES6 縮短。

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

這確實連接唯一了多個數組;

 let Array = [ ['vue','babel','npm','gulp','mysql','less','laravel'], ['jquery','react','js','css','wordpress','html','bootstrap'], ['vue','babel','npm','gulp','mysql','less','laravel'], ['angular','cms','js','css','graphql','nodejs','php'], ['severless','headless','js','css','design','photoshop','php'], ] const Boom = new Set([].concat(...Array)); // This is not necessary let dStr = ''; Boom.forEach(e=>{ dStr += e + ' '; }) document.write(dStr);
 <div class="result"></div>

使用推送合並數組

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

使用ConcatSpread 運算符:

 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);

輕松使用 concat 功能:

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

您可以使用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]);
}

第二個在 chrome 中幾乎慢了 10 倍。

這是一個可以連接多個數組的函數

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]

如果您有數組數組並希望將元素連接到單個數組中,請嘗試以下代碼(需要 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];

如果您不知道否,這種方法很方便。 代碼時的數組。

其中 'n' 是一些數組,可能是一個數組數組。 . .

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

如果只有兩個數組要連接,並且您實際上需要附加一個數組而不是創建一個新數組,則推送或循環是可行的方法。

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

試試這個:

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

i=i.concat(j);

如果 N 個數組是從數據庫中獲取的而不是硬編碼的,我會使用 ES6 這樣做

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

你可以用這個——

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]

似乎正確答案在不同的 JS 引擎中有所不同。 以下是我從ninjagecko 回答中鏈接的測試套件中得到的結果

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

最快的 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);

你可以查看這個博客,這里比較了 push() 和 concat() 的性能。 還制作了自定義功能,在特定場景中表現更好。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM