web-dev-qa-db-fra.com

Comment insérer un élément dans un tableau à un index spécifique (JavaScript)?

Je recherche une méthode d’insertion de tableaux JavaScript dans le style de:

arr.insert(index, item)

De préférence dans jQuery, mais toute implémentation de JavaScript fera l'affaire à ce stade.

2335
tags2k

Ce que vous voulez, c'est la fonction splice sur l'objet tableau natif.

arr.splice(index, 0, item); insérera item dans arr à l'index spécifié (en supprimant les éléments 0 en premier, c'est-à-dire qu'il ne s'agit que d'une insertion).

Dans cet exemple, nous allons créer un tableau et y ajouter un élément dans l'index 2:

var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";

console.log(arr.join());
arr.splice(2, 0, "Lene");
console.log(arr.join());

3846
tvanfosson

Vous pouvez implémenter la méthode Array.insert en procédant comme suit:

Array.prototype.insert = function ( index, item ) {
    this.splice( index, 0, item );
};

Ensuite, vous pouvez l'utiliser comme:

var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
230
FrEsC 81

Autre que l'épissure, vous pouvez utiliser cette approche qui ne mue pas le tableau d'origine, mais crée un nouveau tableau avec l'élément ajouté. Vous devriez généralement éviter les mutations chaque fois que cela est possible. J'utilise l'opérateur ES6 spread ici.

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, newItem) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted item
  newItem,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10)

console.log(result)
// [1, 10, 2, 3, 4, 5]

Cela peut être utilisé pour ajouter plus d'un élément en modifiant légèrement la fonction afin d'utiliser l'opérateur de repos pour les nouveaux éléments et de l'étendre également dans le résultat renvoyé.

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, ...newItems) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted items
  ...newItems,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10, 20)

console.log(result)
// [1, 10, 20, 2, 3, 4, 5]

72
Gaafar

Méthodes personnalisées de tableau insert

1. Avec plusieurs arguments et support de la chaîne

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    this.splice.apply(this, [index, 0].concat(
        Array.prototype.slice.call(arguments, 1)));
    return this;
};

Il peut insérer plusieurs éléments (comme natif splice do) et prend en charge le chaînage

["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]

2. Avec les arguments de type tableau fusionnant et enchaînant le support

/* Syntax:
   array.insert(index, value1, value2, ..., valueN) */

Array.prototype.insert = function(index) {
    index = Math.min(index, this.length);
    arguments.length > 1
        && this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
        && this.insert.apply(this, arguments);
    return this;
};

Il peut fusionner des tableaux à partir des arguments avec le tableau donné et prend également en charge le chaînage:

["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"

DEMO:http://jsfiddle.net/UPphH/

69
VisioN

Si vous souhaitez insérer plusieurs éléments à la fois dans un tableau, consultez cette réponse Stack Overflow: Un meilleur moyen de scinder un tableau en un tableau en javascript

Voici également quelques fonctions pour illustrer ces deux exemples:

function insertAt(array, index) {
    var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
    return insertArrayAt(array, index, arrayToInsert);
}

function insertArrayAt(array, index, arrayToInsert) {
    Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
    return array;
}

Enfin, voici un jsFiddle que vous pourrez voir vous-même: http://jsfiddle.net/luisperezphd/Wc8aS/

Et voici comment vous utilisez les fonctions:

// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");

// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);
33
Luis Perez

Pour que la programmation fonctionnelle et l’enchaînement soient corrects, une invention de Array.prototype.insert() est essentielle. En réalité, splice aurait pu être parfait s'il avait renvoyé le tableau muté au lieu d'un tableau vide totalement dépourvu de sens. Alors voila

Array.prototype.insert = function(i,...rest){
  this.splice(i,0,...rest)
  return this
}

var a = [3,4,8,9];
document.write("<pre>" + JSON.stringify(a.insert(2,5,6,7)) + "</pre>");

Bien ok le dessus avec le Array.prototype.splice() on mute le tableau original et certains pourraient se plaindre comme "vous ne devriez pas modifier ce qui ne vous appartient pas" et cela pourrait également s'avérer juste. Donc, pour le bien-être public, j'aimerais donner une autre Array.prototype.insert() qui ne modifie pas le tableau d'origine. Ici ça va;

Array.prototype.insert = function(i,...rest){
  return this.slice(0,i).concat(rest,this.slice(i));
}

var a = [3,4,8,9],
    b = a.insert(2,5,6,7);
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));

16
Redu

Je recommande d'utiliser pur JavaScript dans ce cas, il n'y a pas non plus de méthode d'insertion en JavaScript, mais nous avons une méthode qui est une méthode intégrée dans Array qui fait le travail pour vous, elle s'appelle épissure ...

Voyons ce qui est splice () ...

La méthode splice () modifie le contenu d'un tableau en supprimant éléments existants et/ou l'ajout de nouveaux éléments.

OK, imaginons que nous avons ce tableau ci-dessous:

const arr = [1, 2, 3, 4, 5];

Nous pouvons supprimer 3 comme ceci:

arr.splice(arr.indexOf(3), 1);

Il retournera 3, mais si nous vérifions l'arr il maintenant, nous avons:

[1, 2, 4, 5]

Jusqu'ici, tout va bien, mais comment pouvons-nous ajouter un nouvel élément au tableau en utilisant splice?.

arr.splice(2, 0, 3);

Voyons ce que nous avons fait ...

Nous utilisons splice encore, mais cette fois pour le deuxième argument, nous passons 0 , cela veut dire que nous ne voulons supprimer aucun élément, mais en même temps, nous ajoutons un troisième argument, le 3, qui sera ajouté. au deuxième index ...

Vous devez savoir que nous pouvons supprimer et ajouter en même temps, par exemple, nous pouvons maintenant:

arr.splice(2, 2, 3);

Ce qui supprimera 2 éléments à l'index 2, puis ajoutera 3 à l'index 2 et le résultat sera:

[1, 2, 3, 5];

Ceci montre comment chaque élément de l'épissure fonctionne:

array.splice (start, deleteCount, item1, item2, item3 ...)

10
Alireza

Même si cela a déjà été répondu, j'ajoute cette note pour une approche alternative.

Je voulais placer un nombre connu d'éléments dans un tableau, dans des positions spécifiques, car ils proviennent d'un "tableau associatif" (c'est-à-dire un objet) qui, par définition, n'est pas garanti d'être dans un ordre trié. Je voulais que le tableau résultant soit un tableau d'objets, mais que les objets soient dans un ordre spécifique dans le tableau puisqu'un tableau garantit leur ordre. Alors j'ai fait ça.

D'abord l'objet source, une chaîne JSONB extraite de PostgreSQL. Je voulais le faire trier par la propriété "order" dans chaque objet enfant.

var jsonb_str = '{"one": {"abbr": "", "order": 3}, "two": {"abbr": "", "order": 4}, "three": {"abbr": "", "order": 5}, "initialize": {"abbr": "init", "order": 1}, "start": {"abbr": "", "order": 2}}';

var jsonb_obj = JSON.parse(jsonb_str);

Puisque le nombre de nœuds dans l'objet est connu, je crée d'abord un tableau avec la longueur spécifiée:

var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);

Ensuite, parcourez l’objet en plaçant les objets temporaires nouvellement créés aux emplacements souhaités du tableau sans qu’il y ait réellement de "tri".

for (var key of Object.keys(jsonb_obj)) {
  var tobj = {};
  tobj[key] = jsonb_obj[key].abbr;

  var position = jsonb_obj[key].order - 1;
  sorted_array[position] = tobj;
}

console.dir(sorted_array);
6
Ville

Une autre solution possible, avec l'utilisation de Array#reduce.

var arr = ["Apple", "orange", "raspberry"],
    arr2 = [1, 2, 4];

function insert(arr, item, index) {
    arr = arr.reduce(function(s, a, i) {
      i == index ? s.Push(item, a) : s.Push(a);
      return s;
    }, []);   
    console.log(arr);
}

insert(arr, "banana", 1);
insert(arr2, 3, 2);

6
kind user

Ajouter un seul élément à un index spécifique

//Append at specific position(here at index 1)
arrName.splice(1, 0,'newName1');
//1: index number, 0: number of element to remove, newName1: new element


//Append at specific position (here at index 3)
arrName[3] = 'newName1';

Ajouter plusieurs éléments à un index spécifique

//Append from index number 1
arrName.splice(1, 0,'newElemenet1', 'newElemenet2', 'newElemenet3');
//1: index number from where append start, 
//0: number of element to remove, 
//newElemenet1,2,3: new elements
5
Srikrushna Pal

J'ai essayé cela et ça fonctionne bien!

var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);

Index est la position où vous souhaitez insérer ou supprimer l'élément . 0 C'est-à-dire que le deuxième paramètre définit le nombre d'éléments de l'index à supprimer. Ce peut être un ou plusieurs.

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
3
Pawan

Tous ceux qui ont encore des problèmes avec celui-ci et qui ont essayé toutes les options ci-dessus sans l'avoir jamais eu. Je partage ma solution, il faut tenir compte du fait que vous ne devez pas énoncer explicitement les propriétés de votre objet par rapport au tableau.

function isIdentical(left, right){
    return JSON.stringify(left) === JSON.stringify(right);
}

function contains(array, obj){
    let count = 0;
    array.map((cur) => {
          if(this.isIdentical(cur, obj)) count++;
    });
    return count > 0;
}

Cela consiste à itérer le tableau de référence et à le comparer à l'objet que vous voulez vérifier, convertir les deux en une chaîne puis itérer si elle correspond. Ensuite, vous pouvez juste compter. Cela peut être amélioré mais c'est là que je me suis installé. J'espère que cela t'aides.

2
Clyde

Profitant de la méthode de réduction comme suit:

function insert(arr, val, index) {
    return index >= arr.length 
        ? arr.concat(val)
        : arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}

Donc, de cette façon, nous pouvons retourner un nouveau tableau (ce sera une manière fonctionnelle - mieux que d’utiliser Push ou splice) avec l’élément inséré à index, et si l’indice est supérieur à la longueur du tableau, il sera inséré à la fin.

2
alejoko

Un peu d'un fil plus ancien, mais je suis d'accord avec Redu ci-dessus, car splice a certainement une interface déroutante. Et la réponse donnée par cdbajorin selon laquelle "il ne renvoie un tableau vide que lorsque le deuxième paramètre est 0. S'il est supérieur à 0, il renvoie les éléments supprimés du tableau" est, tout en étant précis, la preuve du point. L’intention de la fonction est de fusionner ou, comme le disait plus tôt Jakob Keller, "de se joindre ou de se connecter, aussi de changer. Vous avez maintenant un tableau établi que vous êtes en train de modifier et qui impliquerait l’ajout ou la suppression d’éléments ...". la valeur de retour des éléments, le cas échéant, supprimés est au mieux maladroite. Et je conviens à 100% que cette méthode aurait pu être mieux adaptée à l'enchaînement si elle avait rendu ce qui semble naturel, un nouveau tableau avec les éléments épissés ajoutés. Ensuite, vous pouvez faire des choses comme ["19", "17"]. Splice (1,0, "18"). Join ("...") ou ce que vous voulez avec le tableau retourné. Le fait qu'il retourne ce qui a été supprimé est un peu absurde à mon humble avis. Si l’intention de la méthode était de "découper un ensemble d’éléments" et que c’était seulement une intention, peut-être. Il semble que si je ne sais pas ce que je coupe déjà, j’ai probablement peu de raisons de couper ces éléments, n’est-ce pas? Ce serait mieux s'il se comportait comme concat, mapper, réduire, découper, etc. lorsqu'un nouveau tableau est créé à partir du tableau existant plutôt que de transformer le tableau existant. Ceux-ci sont tous chaînables, et cela IS un problème important. Il est plutôt courant de manipuler des tableaux en chaîne. On dirait que la langue doit aller dans un sens ou dans l'autre et essayer de s'y tenir le plus possible. Le javascript étant fonctionnel et moins déclaratif, cela semble juste un étrange écart par rapport à la norme.

1
meem

Voici deux manières:

const array = [ 'My', 'name', 'Hamza' ];

array.splice(2, 0, 'is');

console.log("Method 1 : ", array.join(" "));

OU

Array.prototype.insert = function ( index, item ) {
    this.splice( index, 0, item );
};

const array = [ 'My', 'name', 'Hamza' ];
array.insert(2, 'is');

console.log("Method 2 : ", array.join(" "));
0
M. Hamza Rajput

Voici une fonction de travail que j'utilise dans l'une de mes applications. 

Ceci vérifie si l'exit d'élément

let ifExist = (item, strings = [ '' ], position = 0) => {
     // output into an array with empty string. Important just in case their is no item. 
    let output = [ '' ];
    // check to see if the item that will be positioned exist.
    if (item) {
        // output should equal to array of strings. 
        output = strings;
       // use splice in order to break the array. 
       // use positition param to state where to put the item
       // and 0 is to not replace an index. Item is the actual item we are placing at the prescribed position. 
        output.splice(position, 0, item);
    }
    //empty string is so we do not concatenate with comma or anything else. 
    return output.join("");
};

Et puis je l'appelle ci-dessous. 

ifExist("friends", [ ' ( ', ' )' ], 1)}  // output: ( friends )
ifExist("friends", [ ' - '], 1)}  // output:  - friends 
ifExist("friends", [ ':'], 0)}  // output:   friends: 
0
Lesly Revenge