Quelle est la manière la plus efficace de concaténer des tableaux N?

Réponses:

323

Si vous concaténez plus de deux baies, concat()c'est la voie à suivre pour plus de commodité et des performances probables.

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

Pour concaténer seulement deux tableaux, le fait d' pushaccepter plusieurs arguments constitués d'éléments à ajouter au tableau peut être utilisé à la place pour ajouter des éléments d'un tableau à la fin d'un autre sans produire un nouveau tableau. Avec slice()elle peut aussi être utilisé à la place , concat()mais il semble y avoir aucun avantage de performance de le faire .

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

Dans ECMAScript 2015 et versions ultérieures, cela peut être encore réduit

a.push(...b)

Cependant, il semble que pour les grands tableaux (de l'ordre de 100 000 membres ou plus), la technique passant un tableau d'éléments à push(soit en utilisant apply()l'opérateur de propagation ECMAScript 2015) peut échouer. Pour de tels tableaux, l'utilisation d'une boucle est une meilleure approche. Voir https://stackoverflow.com/a/17368101/96100 pour plus de détails.

Tim Down
la source
1
Je crois que votre test peut avoir une erreur: le a.concat(b)cas de test semble faire inutilement une copie du tableau apuis le jeter.
ninjagecko
1
@ninjagecko: Vous avez raison. Je l'ai mis à jour: jsperf.com/concatperftest/6 . Dans le cas particulier de la création d'un nouveau tableau qui concatène deux tableaux existants, il semble concat()généralement plus rapide. Dans le cas de la concaténation d'un tableau sur un tableau existant en place, push()c'est la voie à suivre. J'ai mis à jour ma réponse.
Tim Down
16
Je peux attester que l'extension d'une seule baie avec plusieurs nouvelles baies à l'aide de la méthode push.apply confère un énorme avantage de performances (~ 100x) par rapport à l'appel concat simple. J'ai affaire à de très longues listes de courtes listes d'entiers, dans v8 / node.js.
chbrown
1
Une manière encore plus concise est a.push (... b);
dinvlad
1
@dinvlad: Vrai, mais uniquement dans les environnements ES6. J'ai ajouté une note à ma réponse.
Tim Down
158
[].concat.apply([], [array1, array2, ...])

edit : preuve d'efficacité: http://jsperf.com/multi-array-concat/7

edit2 : Tim Supinie mentionne dans les commentaires que cela peut entraîner un dépassement de la taille de la pile d'appels par l'interpréteur. Cela dépend peut-être du moteur js, mais j'ai également obtenu "Taille maximale de la pile d'appels dépassée" sur Chrome au moins. Cas de test: [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (J'ai également eu la même erreur en utilisant la réponse actuellement acceptée, donc on anticipe de tels cas d'utilisation ou on construit une bibliothèque pour d'autres, des tests spéciaux peuvent être nécessaires quelle que soit la solution que vous choisissez.)

ninjagecko
la source
3
@ c69: il semble à peu près aussi efficace que la réponse choisie de répéter .push (#, #, ..., #), sur Chrome au moins. jsperf.com/multi-array-concat La réponse choisie par Tim Down peut également contenir une erreur. Ce lien est une comparaison des performances de la jonction de plusieurs baies comme la question posée (pas seulement 2); plusieurs longueurs possibles sont testées.
ninjagecko
OMI, c'est le moyen le plus efficace de "fusionner" n tableaux, bien joué
Eric Uldall
Cette réponse est particulièrement utile lorsque N n'est pas connu à l'avance, par exemple lorsque vous avez un tableau de tableaux de longueur arbitraire et que vous souhaitez qu'ils soient tous concaténés.
jfriend00
3
Avec ES6 et les opérateurs répartis, c'est encore plus simple: [] .concat (... [array1, array2, ...]) Eh bien, les trois derniers points sont un peu malheureux. Les trois premiers sont l'opérateur de diffusion developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Eydrian
Eydrian: J'essaie personnellement d'éviter l'opérateur de propagation parce qu'il est très inefficace, mais je ne suis pas encore sûr si c'est parce que l'implémentation est immature, ou la sémantique de la spécification es6 nécessite un peu de levage plus lourd (c'est-à-dire qu'elle ne s'améliorera jamais ). Je n'ai cependant pas exécuté de benchmarks dans ce cas particulier.
ninjagecko
34

Pour les personnes utilisant ES2015 (ES6)

Vous pouvez maintenant utiliser la syntaxe Spread pour concaténer des tableaux:

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
la source
Est-ce efficace? D'après ce que j'ai testé, cela est très lent pour les tableaux contenant des objets, voir: jsperf.com/array-concat-vs-array-push-vs-array-spread/1
hitautodestruct
28

La concat()méthode est utilisée pour joindre deux ou plusieurs tableaux. Il ne modifie pas les tableaux existants, il ne renvoie qu'une copie des tableaux joints.

array1 = array1.concat(array2, array3, array4, ..., arrayN);
dogbane
la source
1
Parfois, je déteste JavaScript pour ne pas avoir modifié le tableau d'origine. 🙄
Vincent Hoch-Drei
@ VincentHoch-Drei concatest spécifiquement utilisé pour créer de nouveaux tableaux sans muter le tableau d'origine. Si vous souhaitez mettre à jour array1, vous devez utiliserarray1.push(...array2, ...array3, ...array4)
adiga
24

Utilisez Array.prototype.concat.apply pour gérer la concaténation de plusieurs tableaux:

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

Exemple:

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
la source
1
J'aime celui la! Fonctionne facilement avec un nombre variable de tableaux à concaténer. +1
Joel
14

Si vous êtes en train de passer le résultat par carte / filtre / tri, etc. et que vous souhaitez concaténer un tableau de tableaux, vous pouvez utiliser 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
la source
14

Pour un tableau de plusieurs baies et ES6, utilisez

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

Par exemple:

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
la source
1
De plus, vous pouvez supprimer les éléments en double à l'aide de newArr = Array.from(new Set(newArr));.
Darius M.
Pourquoi cela devient-il en tapuscrit any[]? La dactylographie est là - bizarre.
Simon_Weaver
C'est en fait assez horriblement inefficace pour des volumes de baie plus importants. jsperf.com/flatten-array-203948 [].concat.apply([], ...arr) fonctionne bien mieux sur de gros volumes.
colemars
7

Maintenant, nous pouvons combiner plusieurs tableaux en utilisant ES6 Spread. Au lieu d'utiliser concat()pour concaténer des tableaux, essayez d'utiliser la syntaxe d'étalement pour combiner plusieurs tableaux en un seul tableau aplati. par exemple:

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
la source
5

résolu comme ça.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));
Th1
la source
Solution parfaite.
nehem
4

Vous pouvez utiliser le site jsperf.com pour comparer les performances. Voici le lien pour concat .

Ajout d'une comparaison entre:

var c = a.concat(b);

et:

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

Le second est presque 10 fois plus lent en chrome.

gor
la source
Cependant, vous pouvez l'utiliser push.apply(), ce qui semble être plus rapide que concat()dans tous les navigateurs sauf Chrome. Voir ma réponse.
Tim Down
3

Voici une fonction par laquelle vous pouvez concaténer plusieurs nombres de tableaux

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

    return newArr;
}

Exemple -

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

affichera

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

Fusionner un tableau avec Push:

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

Utilisation de l' opérateur Concat et 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);

Zobia Kanwal
la source
2

Si vous disposez d'un tableau de tableaux et que vous souhaitez concaténer les éléments en un seul tableau, essayez le code suivant (nécessite 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];

Ou si vous aimez la programmation fonctionnelle

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

Ou encore mieux avec la syntaxe ES5, sans l'opérateur de propagation

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

Cette façon est pratique si vous ne connaissez pas le non. des tableaux au moment du code.

Noob
la source
2

Raccourcissez avec ES6.

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

Cela concatène et unique les tableaux multiples;

Démo sur codepen

ronaldtgi
la source
il le fait mais il supprime les doublons .. que faire si je ne veux pas supprimer les tableaux en double?
Krunal Shah
new Set()ne supprime pas les éléments en double. Retirez-le. [].concat(...Array)
ronaldtgi
je veux utiliser un nouveau Set ([]. concat (... Array)); mais je veux aussi supprimer les doublons avec lui dans une seule expression. c'est possible ?
Krunal Shah
1

où 'n' est un certain nombre de tableaux, peut-être un tableau de tableaux. . .

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

rashadb
la source
0

essaye ça:

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

i=i.concat(j);
JAiro
la source
@reggie, vous avez tous les deux copié-collé à partir de la même source;)
I.devries
non, je dois vérifier les informations dans le même lien que vous. ilovethecode.com/Javascript/Javascript-Tutorials-How_To-Easy/…
JAiro
ouais ... Je suppose que nous l'avons obtenu de la même source: D
reggie
au moins @JAiro a changé le contenu du tableau. @reggie ne l'a pas fait. :)
dogbane
c'est la même chose, l'important est d'aider les gens à résoudre ses problèmes :)
JAiro
0

si les tableaux N proviennent de la base de données et ne sont pas codés en dur, je le ferai comme ceci en utilisant ES6

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