Was ist der effizienteste Weg, um N Arrays zu verketten?

Antworten:

323

Wenn Sie mehr als zwei Arrays verketten, concat()ist dies der richtige Weg, um Komfort und wahrscheinliche Leistung zu erzielen.

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

Um nur zwei Arrays zu verketten, kann die Tatsache, dass pushmehrere Argumente akzeptiert werden, die aus Elementen bestehen, die dem Array hinzugefügt werden sollen, stattdessen verwendet werden, um Elemente von einem Array zum Ende eines anderen hinzuzufügen, ohne ein neues Array zu erzeugen. Mit slice()kann es auch anstelle von verwendet werden, concat()aber es scheint keinen Leistungsvorteil zu geben, wenn dies getan wird .

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

In ECMAScript 2015 und höher kann dies noch weiter reduziert werden

a.push(...b)

Es scheint jedoch, dass bei großen Arrays (in der Größenordnung von 100.000 Mitgliedern oder mehr) die Technik, an die ein Array von Elementen übergeben wird push(entweder unter Verwendung apply()oder des ECMAScript 2015-Spread-Operators), fehlschlagen kann. Für solche Arrays ist die Verwendung einer Schleife ein besserer Ansatz. Weitere Informationen finden Sie unter https://stackoverflow.com/a/17368101/96100 .

Tim Down
quelle
1
Ich glaube, Ihr Test hat möglicherweise einen Fehler: Der a.concat(b)Testfall scheint unnötig eine Kopie des Arrays zu erstellen und aes dann wegzuwerfen.
Ninjagecko
1
@ninjagecko: Du hast recht. Ich habe es aktualisiert: jsperf.com/concatperftest/6 . Für den speziellen Fall, dass ein neues Array erstellt wird, das zwei vorhandene Arrays verkettet, scheint concat()es im Allgemeinen schneller zu sein. Für den Fall der Verkettung eines Arrays mit einem vorhandenen Array push()ist dies der richtige Weg. Ich habe meine Antwort aktualisiert.
Tim Down
16
Ich kann bestätigen, dass die Erweiterung eines einzelnen Arrays mit mehreren neuen Arrays mithilfe der push.apply-Methode einen großen Leistungsvorteil (~ 100x) gegenüber dem einfachen Concat-Aufruf bietet. Ich habe es mit sehr langen Listen von kurzen Listen von ganzen Zahlen in v8 / node.js zu tun.
chbrown
1
Ein noch prägnanterer Weg ist a.push (... b);
Dinvlad
1
@dinvlad: Richtig, aber nur in ES6-Umgebungen. Ich habe meiner Antwort eine Notiz hinzugefügt.
Tim Down
158
[].concat.apply([], [array1, array2, ...])

Bearbeiten : Effizienznachweis: http://jsperf.com/multi-array-concat/7

edit2 : Tim Supinie erwähnt in den Kommentaren, dass dies dazu führen kann, dass der Interpreter die Größe des Aufrufstapels überschreitet. Dies hängt möglicherweise von der js-Engine ab, aber ich habe auch zumindest in Chrome die Option "Maximale Call-Stack-Größe überschritten" erhalten. Testfall : [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (Ich habe auch den gleichen Fehler bei der Verwendung der aktuell akzeptierten Antwort erhalten, sodass man solche Anwendungsfälle vorwegnimmt oder eine Bibliothek für andere erstellt. Je nachdem, welche Lösung Sie wählen, sind möglicherweise spezielle Tests erforderlich.)

Ninjagecko
quelle
3
@ c69: Es scheint ungefähr so ​​effizient zu sein wie die gewählte Antwort von wiederholt .push (#, #, ..., #), zumindest auf Chrome. jsperf.com/multi-array-concat Die von Tim Down gewählte Antwort enthält möglicherweise auch einen Fehler. Dieser Link ist ein Leistungsvergleich zum Verbinden mehrerer Arrays als gestellte Frage (nicht nur 2). Es werden mehrere mögliche Längen getestet.
Ninjagecko
IMO ist dies der effektivste Weg, um n Arrays "zusammenzuführen", gut gemacht
Eric Uldall
Diese Antwort ist besonders nützlich, wenn N nicht im Voraus bekannt ist, z. B. wenn Sie ein Array von Arrays beliebiger Länge haben und alle verketten möchten.
jfriend00
3
Mit ES6- und Spread-Operatoren wird es noch einfacher: [] .concat (... [array1, array2, ...]) Nun, die zweiten drei Punkte sind etwas unglücklich. Die ersten drei ist der Spread-Operator developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Eydrian
Eydrian: Ich persönlich versuche, den Spread-Operator zu vermeiden, weil er sehr ineffizient ist, aber ich bin mir noch nicht sicher, ob dies daran liegt, dass die Implementierung noch nicht ausgereift ist oder die Semantik der es6-Spezifikation etwas schwereres Heben erfordert (dh es wird nie besser werden) ). In diesem speziellen Fall wurden jedoch keine Benchmarks ausgeführt.
Ninjagecko
34

Für Benutzer von ES2015 (ES6)

Sie können jetzt die Spread-Syntax verwenden, um Arrays zu verketten:

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]
Duncan Luk
quelle
Wie effizient ist das? Nach dem,
hitautodestruct
28

Die concat()Methode wird verwendet, um zwei oder mehr Arrays zu verbinden. Die vorhandenen Arrays werden nicht geändert, sondern nur eine Kopie der verknüpften Arrays zurückgegeben.

array1 = array1.concat(array2, array3, array4, ..., arrayN);
Dogbane
quelle
1
Manchmal hasse ich JavaScript, weil es das ursprüngliche Array nicht modifiziert. 🙄
Vincent Hoch-Drei
@ VincentHoch-Drei concatwird speziell zum Erstellen neuer Arrays verwendet, ohne das ursprüngliche Array zu mutieren. Wenn Sie aktualisieren möchten array1, müssen Siearray1.push(...array2, ...array3, ...array4)
adiga
24

Verwenden Sie Array.prototype.concat.apply, um die Verkettung mehrerer Arrays zu verarbeiten:

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

Beispiel:

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]
Burnee
quelle
1
Ich mag diesen! Funktioniert problemlos mit einer variablen Anzahl von zu verkettenden Arrays. +1
Joel
14

Wenn Sie gerade dabei sind, das Ergebnis durch Map / Filter / Sort usw. zu leiten, und Sie ein Array von Arrays zusammenfassen möchten, können Sie es verwenden 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']
artnikpro
quelle
14

Verwenden Sie für ein Array mit mehreren Arrays und ES6

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

Beispielsweise:

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 ]
David
quelle
1
Außerdem können Sie doppelte Elemente mit entfernen newArr = Array.from(new Set(newArr));.
Darius M.
Warum wird dies im Typoskript any[]? Das Tippen ist da - komisch.
Simon_Weaver
Dies ist bei größeren Array-Volumes tatsächlich ziemlich schrecklich ineffizient. jsperf.com/flatten-array-203948 bietet [].concat.apply([], ...arr) bei großen Volumes eine deutlich bessere Leistung.
Colemars
7

Jetzt können wir mehrere Arrays mit kombinieren ES6 Spread. concat()Versuchen Sie, mithilfe der Spread-Syntax mehrere Arrays zu einem reduzierten Array zu kombinieren, anstatt Arrays zu verketten. z.B:

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]
Chinmayan
quelle
5

so gelöst.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));
Th1
quelle
Perfekte Lösung.
Nehem
4

Sie können die Website jsperf.com verwenden , um die Leistung zu vergleichen. Hier ist der Link zu concat .

Vergleich hinzugefügt zwischen:

var c = a.concat(b);

und:

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

Der zweite ist in Chrom fast zehnmal langsamer.

gor
quelle
Sie können jedoch verwenden push.apply(), was schneller zu sein scheint als concat()in allen Browsern außer Chrome. Siehe meine Antwort.
Tim Down
3

Hier ist eine Funktion, mit der Sie mehrere Arrays verketten können

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

    return newArr;
}

Beispiel -

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

wird ausgegeben

[1,2,3,5,2,1,4,2,8,9]
Koushik Das
quelle
2

Wenn Sie ein Array von Arrays haben und die Elemente zu einem einzigen Array zusammenfassen möchten, versuchen Sie den folgenden Code (erfordert 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];

Oder wenn Sie sich für funktionale Programmierung interessieren

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

Oder noch besser mit ES5-Syntax ohne den Spread-Operator

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

Dieser Weg ist praktisch, wenn Sie die Nr. Nicht kennen. von Arrays zur Codezeit.

Anfänger
quelle
2

Mit ES6 kürzen.

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

Dadurch werden die mehreren Arrays konkattiert und eindeutig .

Demo auf Codepen

ronaldtgi
quelle
es tut, aber es entfernt Duplikate .. was ist, wenn ich keine doppelten Arrays entfernen möchte?
Krunal Shah
new Set()entfernt doppelte Elemente. Entfernen Sie es einfach. [].concat(...Array)
Ronaldtgi
Ich möchte neues Set ([]. concat (... Array)) verwenden. Ich möchte aber auch Duplikate in einem einzigen Ausdruck entfernen. ist es möglich ?
Krunal Shah
2

Array mit Push zusammenführen:

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

Verwenden des Concat and Spread-Operators:

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

Zobia Kanwal
quelle
1

Dabei ist 'n' eine Anzahl von Arrays, möglicherweise ein Array von Arrays. . .

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

Rashadb
quelle
0

Versuche dies:

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

i=i.concat(j);
JAiro
quelle
@reggie, ihr beide habt aus derselben Quelle
kopiert
Nein, ich habe die Informationen im selben Link wie Sie überprüft. ilovethecode.com/Javascript/Javascript-Tutorials-How_To-Easy/…
JAiro
Ja ... ich denke, wir haben es aus derselben Quelle erhalten: D
Reggie
Zumindest @JAiro hat den Array-Inhalt geändert. @reggie nicht. :)
Dogbane
es ist das gleiche, das Wichtigste ist, den Menschen zu helfen, ihre Probleme zu lösen :)
JAiro
0

Wenn die N Arrays aus der Datenbank stammen und nicht fest codiert sind, mache ich das mit ES6 so

let get_fruits = [...get_fruits , ...DBContent.fruit];
Akinnifesi Damilola
quelle