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.


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


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]

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

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]

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

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 ]

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]

5

résolu comme ça.

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

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.


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]

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


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.


2

Raccourcissez avec ES6.

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

Cela concatène et unique les tableaux multiples;

Démo sur codepen


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



0

essaye ça:

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

i=i.concat(j);

@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];
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.