web-dev-qa-db-fra.com

Javascript - insérer un tableau dans un autre tableau

Quel est le moyen le plus efficace d’insérer un tableau dans un autre tableau? 

a1 = [1,2,3,4,5];
a2 = [21,22];

newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];

Itérer a2 avec splice semble un peu gênant du point de vue performance si le tableau a2 est grand.

Merci.

66
ic3

Vous pouvez utiliser splice associé à une astuce apply:

a1 = [1,2,3,4,5];
a2 = [21,22];

a1.splice.apply(a1, [2, 0].concat(a2));

console.log(a1); // [1, 2, 21, 22, 3, 4, 5];

Dans ES2015 +, vous pouvez utiliser l'opérateur de diffusion à la place pour rendre cela un peu plus agréable.

a1.splice(2, 0, ...a2);
139
nickf

Avait-il mal au début. Aurait dû utiliser concat() à la place.

var a1 = [1,2,3,4,5];
var a2 = [21,22];

var result = a1.slice( 0, 2 ).concat( a2 ).concat( a1.slice( 2 ) );

Exemple:http://jsfiddle.net/f3cae/1/

Cela prend un slice()[docs] of a1 jusqu’à l’index, puis un concat()[docs] pour ajouter a2 à ce tableau, utilise ensuite .concat() en prenant à nouveau .slice() de a1, mais cette fois en commençant par le même index.

Et ajoutez-le à Array.prototype si vous le souhaitez:

Exemple:http://jsfiddle.net/f3cae/2/

Array.prototype.injectArray = function( idx, arr ) {
    return this.slice( 0, idx ).concat( arr ).concat( this.slice( idx ) );
};

var a1 = [1,2,3,4,5];
var a2 = [21,22];

var result = a1.injectArray( 2, a2 );

Vous pouvez utiliser le splice()[docs] méthode sans itération.

a1.splice( 2, 0, a2 );

http://jsfiddle.net/f3cae/ </ s>

11
user113716

Vous pouvez maintenant le faire si vous utilisez ES2015 ou une version ultérieure:

var a1 = [1,2,3,4,5];
var a2 = [21,22];
a1.splice(2, 0, ...a2);
console.log(a1) // => [1,2,21,22,3,4,5]

Reportez-vous à cela pour la documentation sur l'opérateur de propagation (...) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

8
Elmer

Je voulais trouver un moyen de faire cela avec splice() sans itérer: http://jsfiddle.net/jfriend00/W9n27/ .

a1 = [1,2,3,4,5];
a2 = [21,22];

a2.unshift(2, 0);          // put first two params to splice onto front of array
a1.splice.apply(a1, a2);   // pass array as arguments parameter to splice
console.log(a1);           // [1, 2, 21, 22, 3, 4, 5];

Sous forme de fonction d'usage général:

function arrayInsertAt(destArray, pos, arrayToInsert) {
    var args = [];
    args.Push(pos);                           // where to insert
    args.Push(0);                             // nothing to remove
    args = args.concat(arrayToInsert);        // add on array to insert
    destArray.splice.apply(destArray, args);  // splice it in
}
2
jfriend00

L'opérateur spread permet de développer une expression là où plusieurs arguments (pour les appels de fonction) ou plusieurs éléments (pour les littéraux de tableau) sont attendus.

a2 = [21,22];
a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator
console.log(a1);

1
Hek mat

Si vous souhaitez insérer un autre tableau dans un tableau sans en créer un nouveau, le moyen le plus simple consiste à utiliser Push ou unshift avec apply.

Par exemple:

a1 = [1,2,3,4,5];
a2 = [21,22];

// Insert a1 at beginning of a2
a2.unshift.apply(a2,a1);
// Insert a1 at end of a2
a2.Push.apply(a2,a1);

Cela fonctionne parce que Push et unshift prennent un nombre variable d'arguments . Un bonus, vous pouvez facilement choisir l'extrémité à laquelle attacher le tableau!

1
RangerMauve

Comme mentionné dans un autre sujet, les réponses ci-dessus ne fonctionneront pas dans de très grands tableaux (200K éléments). Voir autre réponse ici concernant l’épissure et le mode manuel. Push: https://stackoverflow.com/a/41465578/1038326

Array.prototype.spliceArray = function(index, insertedArray) {
    var postArray = this.splice(index);
    inPlacePush(this, insertedArray);
    inPlacePush(this, postArray);

    function inPlacePush(targetArray, pushedArray) {
  // Not using forEach for browser compatability
        var pushedArrayLength = pushedArray.length;
        for (var index = 0; index < pushedArrayLength; index++) {
           targetArray.Push(pushedArray[index]);
       }
    }
}
0
Gabriel Kohen

Il existe des réponses vraiment créatives à cette question ici. Voici une solution simple pour ceux qui débutent avec les tableaux. Si vous le souhaitez, vous pouvez le faire fonctionner jusqu'aux navigateurs compatibles ECMAScript 3.

Savoir quelque chose sur l'épissure avant de commencer.

Réseau de développeurs Mozilla: Array.prototype.splice ()

Commencez par comprendre deux formes importantes de .splice().

let a1 = [1,2,3,4],
    a2 = [1,2];

Méthode 1) Supprimez les éléments x (deleteCount) à partir de l'index souhaité.

let startIndex = 0, 
    deleteCount = 2;

a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

Méthode 2) Supprimez les éléments après un index de début souhaité à la fin du tableau.

a1.splice(2); // returns [3,4], a1 would be [1,2]

Avec .splice(), un objectif pourrait être de scinder a1 en tableaux de tête et de queue en utilisant l’un des deux formulaires ci-dessus.

En utilisant la méthode n ° 1, la valeur de retour deviendrait la tête et a1 la queue.

let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

Maintenant, en un seul coup, concaténez la tête, le corps (a2) et la queue

[].concat(head, a2, a1);

Ainsi, cette solution ressemble plus au monde réel qu’aucune autre présentée jusqu’à présent. N'est-ce pas ce que vous feriez avec Legos? ;-) Voici une fonction réalisée à l'aide de la méthode n ° 2.

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
    let tail = target.splice(startIndex); // target is now [1,2] and the head
    return [].concat(target, body, tail);
}

let newArray = insertArray([1, 2, 3, 4], ["a", "b"], 2); // [1, 2, "a", "b", 3, 4]

Plus court:

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
    return [].concat(target, body, target.splice(startIndex));
}

Plus sûr:

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*@throws Error The value for startIndex must fall between the first and last index, exclusive.
*/
function insertArray(target, body, startIndex)
{
    const ARRAY_START = 0,
          ARRAY_END = target.length - 1,
          ARRAY_NEG_END = -1,
          START_INDEX_MAGNITUDE = Math.abs(startIndex);

    if (startIndex === ARRAY_START) {
        throw new Error("The value for startIndex cannot be zero (0).");
    }

    if (startIndex === ARRAY_END || startIndex === ARRAY_NEG_END) {
        throw new Error("The startIndex cannot be equal to the last index in target, or -1.");
    }

    if (START_INDEX_MAGNITUDE >= ARRAY_END) {
        throw new Error("The absolute value of startIndex must be less than the last index.");
    }

    return [].concat(target, body, target.splice(startIndex));
}

Les avantages de cette solution incluent:

1) Un principe simple domine la solution - remplissez un tableau vide.

2) La nomenclature de la tête, du corps et de la queue semble naturelle.

3) Pas de double appel à .slice(). Pas de tranchage du tout.

4) Non .apply(). Très inutile.

5) Le chaînage des méthodes est évité.

6) Fonctionne dans ECMAScript 3 et 5 en utilisant simplement var au lieu de let ou const.

** 7) Garantit qu’il y aura une tête et une queue sur le corps, contrairement à de nombreuses autres solutions présentées. Si vous ajoutez un tableau avant ou après les limites, vous devriez au moins utiliser .concat() !!!!

Remarque: L’utilisation du spreadcode ... facilite tout cela.

0
Anthony Rutledge

Voici ma version sans astuces spéciales:

function insert_array(original_array, new_values, insert_index) {
    for (var i=0; i<new_values.length; i++) {
        original_array.splice((insert_index + i), 0, new_values[i]);
    }
    return original_array;
}
0
arlomedia
var a1 = [1,2,3,4,5];
var a2 = [21,22];

function injectAt(d, a1, a2) {
    for(var i=a1.length-1; i>=d; i--) {
        a1[i + a2.length] = a1[i];
    }
    for(var i=0; i<a2.length; i++) {
        a1[i+d] = a2[i];
    }
}

injectAt(2, a1, a2);

alert(a1);
0
Bhesh Gurung