Comment puis-je supprimer un élément spécifique d'un tableau?


8300

J'ai un tableau de nombres et j'utilise la .push()méthode pour y ajouter des éléments.

Existe-t-il un moyen simple de supprimer un élément spécifique d'un tableau?

Je cherche l'équivalent de quelque chose comme:

array.remove(number);

Je dois utiliser le noyau JavaScript. Les cadres ne sont pas autorisés.

Réponses:


11899

Recherchez l' indexélément de tableau que vous souhaitez supprimer à l'aide de indexOf, puis supprimez cet index avec splice.

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

const array = [2, 5, 9];

console.log(array);

const index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}

// array = [2, 9]
console.log(array); 

Le deuxième paramètre de spliceest le nombre d'éléments à supprimer. Notez que splicemodifie le tableau en place et renvoie un nouveau tableau contenant les éléments qui ont été supprimés.


Pour des raisons d'exhaustivité, voici les fonctions. Première fonction supprime uniquement occurrence unique ( à savoir la suppression de la première partie 5de [2,5,9,1,5,8,5]), tandis que la deuxième fonction supprime toutes les occurrences:

function removeItemOnce(arr, value) { 
    var index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}

function removeItemAll(arr, value) {
    var i = 0;
    while (i < arr.length) {
        if(arr[i] === value) {
            arr.splice(i, 1);
        } else {
            ++i;
        }
    }
    return arr;
}

15
@Peter, oui, vous avez peut-être raison. Cet article explique plus et propose une solution de contournement pour les navigateurs incompatibles: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley

33
@AlexandreWiechersVaz Bien sûr, il préserve l'ordre, sinon, ce serait absolument sans valeur
TheZ

15
Vous pouvez surmonter le problème de prise en charge du navigateur IE en incluant le code donné ici

15
@AdrianP. array.indexOf(testValue)sur un tableau vide sera -1, et si vous testez cela, alors aucune épissure. Peut-être que la réponse a changé depuis.
UpTheCreek

13
IE 7, IE8, IE9, IE10 ne sont pas pris en charge par Microsoft lui-même, pourquoi les développeurs Web devraient-ils prendre en charge ces anciens navigateurs? Affichez simplement une notification sur la mise à niveau du navigateur! support.microsoft.com/en-us/lifecycle/…
Lukas Liesis

1269

Je ne sais pas comment tu t'attends à te array.remove(int)comporter. Il y a trois possibilités auxquelles je peux penser que vous voudrez peut-être.

Pour supprimer un élément d'un tableau à un index i:

array.splice(i, 1);

Si vous souhaitez supprimer tous les éléments avec valeur numberdu tableau:

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
        array.splice(i, 1);
    }
}

Si vous voulez simplement que l'élément de l'index in'existe plus, mais que vous ne voulez pas que les index des autres éléments changent:

delete array[i];

335
deleten'est pas la bonne façon de supprimer un élément d'un tableau!
Felix Kling du

71
@FelixKling Cela dépend, cela fonctionne si vous voulez faire en sorte que array.hasOwnProperty(i)retourne falseet que l'élément à cette position revienne undefined. Mais je dois admettre que ce n'est pas une chose très courante à vouloir faire.
Peter Olson

88
deletene mettra pas à jour la longueur du tableau ni n'effacera vraiment l'élément, le remplacera uniquement par la valeur spéciale undefined.
diosney

34
@diosney Je ne sais pas ce que tu veux dire quand tu dis que ça n'efface pas vraiment l'élément. De plus, il fait plus que simplement remplacer la valeur de cet index par undefined: il supprime à la fois l'index et la valeur du tableau, c'est-à-dire après delete array[0], "0" in arrayretournera false.
Peter Olson

17
@GrantGryczan Désolé, je ne suis pas d'accord. Je ne vois pas la nécessité de supprimer cela. Le texte ci-dessus explique clairement ce qu'il fait, et il aide les personnes qui ne savent pas quoi deletefaire à comprendre pourquoi cela ne fonctionne pas comme prévu.
Peter Olson

1207

Édité en octobre 2016

  • Faites-le simple, intuitif et explicite ( rasoir d'Occam )
  • Faites-le immuable (le tableau d'origine reste inchangé)
  • Faites-le avec les fonctions JavaScript standard, si votre navigateur ne les prend pas en charge - utilisez polyfill

Dans cet exemple de code, j'utilise la fonction "array.filter (...)" pour supprimer les éléments indésirables d'un tableau. Cette fonction ne modifie pas le tableau d'origine et en crée un nouveau. Si votre navigateur ne prend pas en charge cette fonction (par exemple, Internet Explorer avant la version 9 ou Firefox avant la version 1.5), pensez à utiliser le filtre polyfill de Mozilla .

Suppression d'un élément (code ECMA-262 Edition 5 aka oldstyle JavaScript)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) {
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

Suppression d'un élément (code ECMAScript 6)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

IMPORTANT La syntaxe de la fonction de flèche ECMAScript 6 "() => {}" n'est pas du tout prise en charge dans Internet Explorer, Chrome avant la version 45, Firefox avant la version 22 et Safari avant la version 10. Pour utiliser la syntaxe ECMAScript 6 dans les anciens navigateurs, vous pouvez utiliser BabelJS .


Suppression de plusieurs éléments (code ECMAScript 7)

Un avantage supplémentaire de cette méthode est que vous pouvez supprimer plusieurs éléments

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

La fonction "array.includes (...)" n'est pas du tout prise en charge dans Internet Explorer, Chrome avant la version 47, Firefox avant la version 43, Safari avant la version 9 et Edge avant la version 14 donc voici polyfill de Mozilla .

Suppression de plusieurs éléments (à l'avenir, peut-être)

Si la proposition "This-Binding Syntax" est acceptée, vous pourrez le faire:

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

Essayez-le vous-même dans BabelJS :)

Référence


6
mais, parfois, nous voulons supprimer l'élément du tableau d'origine (non immuable), par exemple le tableau utilisé dans la directive Angular 2 * ngFor
Ravinder Payal

43
Mieux que la solution acceptée car elle ne suppose pas une seule occurrence d'un match et l'immuabilité est préférable
Greg

13
filterdoit être beaucoup plus lent pour un grand tableau?
Nathan

3
Quel est le point d'immuabilité mentionné si vous avez utilisé l'attribution de la même variable dans vos exemples? :)
mench

12
C'est une excellente réponse. Splice est une fonction spécialisée pour muter et non filtrer. filterpeut avoir des performances plus lentes mais c'est un code plus sûr et meilleur. En outre, vous pouvez filtrer par index en spécifiant un deuxième argument dans le lambda:arr.filter((x,i)=>i!==2)
Matthew

449

Cela dépend si vous souhaitez conserver un emplacement vide ou non.

Si vous voulez un emplacement vide, la suppression est très bien:

delete array[index];

Si vous ne le faites pas, vous devez utiliser la méthode d' épissage :

array.splice(index, 1);

Et si vous avez besoin de la valeur de cet élément, vous pouvez simplement stocker l'élément du tableau retourné:

var value = array.splice(index, 1)[0];

Dans le cas où vous souhaitez le faire dans un certain ordre, vous pouvez utiliser array.pop()pour le dernier ou array.shift()pour le premier (et les deux renvoient également la valeur de l'article).

Et si vous ne connaissez pas l'index de l'élément, vous pouvez l'utiliser array.indexOf(item)pour l'obtenir (dans un if()pour obtenir un élément ou dans un while()pour les obtenir tous). array.indexOf(item)renvoie l'index ou -1 s'il n'est pas trouvé. 


25
deleten'est pas la bonne façon de supprimer un élément d'un tableau !!
Progo

16
Si vous souhaitez "vider un emplacement", utilisez array[index] = undefined;. L'utilisation deletedétruira l'optimisation.
Bergi

4
@Jakub très bon commentaire car pour comprendre que j'ai perdu beaucoup de temps et que mon code d'application est en quelque sorte cassé ...
Pascal

Le dernier paragraphe avec l'explication de ce que vous obtenez d'indexOf a été vraiment utile
A. D'Alfonso

277

Un ami avait des problèmes Internet Explorer 8 et m'a montré ce qu'il avait fait. Je lui ai dit que c'était mal, et il m'a dit qu'il avait obtenu la réponse ici. La première réponse actuelle ne fonctionnera pas dans tous les navigateurs (Internet Explorer 8 par exemple) et supprimera uniquement la première occurrence de l'élément.

Supprimer TOUTES les instances d'un tableau

function remove(arr, item) {
    for (var i = arr.length; i--;) {
        if (arr[i] === item) {
            arr.splice(i, 1);
        }
    }
}

Il parcourt le tableau en arrière (puisque les indices et la longueur changeront à mesure que les éléments sont supprimés) et supprime l'élément s'il est trouvé. Cela fonctionne dans tous les navigateurs.


11
@sroes cela ne devrait pas être parce que la boucle commence à i = arr.length -1ou la i--rend identique à l'index max arr.lengthest juste une valeur initiale pour i. i--sera toujours véridique (et réduira de 1 à chaque boucle) jusqu'à ce qu'il soit égal 0(une valeur fausse) et la boucle s'arrêtera alors.
gmajivu

1
La deuxième fonction est plutôt inefficace. À chaque itération, "indexOf" commencera la recherche depuis le début du tableau.
ujeenator

3
@AmberdeBlack, sur une collection avec plus d'une occurrence d' élément , il est préférable d'appeler la méthode de filtrage à la place arr.filter(function (el) { return el !== item }), en évitant d'avoir à muter le tableau plusieurs fois. Cela consomme un peu plus de mémoire, mais fonctionne beaucoup plus efficacement, car il y a moins de travail à faire.
Eugene Kuzmenko

1
@AlJey, il est disponible uniquement à partir d'IE9 +. Il y a toujours une chance que cela ne fonctionne pas.
ujeenator

1
Cette réponse a fonctionné pour moi car j'avais besoin de plusieurs éléments supprimés mais pas dans un ordre particulier. La progression vers l'arrière de la boucle for gère parfaitement la suppression des éléments du tableau.
mintedsky

172

Il existe deux approches principales:

  1. épissure () :anArray.splice(index, 1);

  2. supprimer :delete anArray[index];

Soyez prudent lorsque vous utilisez la suppression pour un tableau. C'est bon pour supprimer les attributs des objets, mais pas si bon pour les tableaux. Il vaut mieux utilisersplice pour les tableaux.

Gardez à l'esprit que lorsque vous utilisez deleteun tableau, vous pouvez obtenir des résultats erronés anArray.length. En d'autres termes, deletesupprimerait l'élément, mais ne mettrait pas à jour la valeur de la propriété length.

Vous pouvez également vous attendre à avoir des trous dans les numéros d'index après avoir utilisé la suppression, par exemple, vous pourriez vous retrouver avec les index 1, 3, 4, 8, 9 et 11 et la longueur comme avant l'utilisation de la suppression. Dans ce cas, toutes les forboucles indexées se bloqueraient, car les index ne sont plus séquentiels.

Si vous êtes obligé d'utiliser deletepour une raison quelconque, vous devez utiliser des for eachboucles lorsque vous devez parcourir des tableaux. En fait, évitez toujours d'utiliser des forboucles indexées , si possible. De cette façon, le code serait plus robuste et moins sujet aux problèmes d'index.


144
Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)


14
Je ne suis pas un grand fan de cette approche. Si vous finissez par utiliser des bibliothèques ou des cadres différents, ils peuvent finir par entrer en conflit les uns avec les autres.
Charlie Kilian


10
Si vous faites un for insur un tableau, vous avez déjà un problème.
Zirak

2
si tu fais for in sur des tableaux, vous avez déjà de plus gros problèmes.
Rainb

utilisez Object.defineProperty stackoverflow.com/a/35518127/3779853 et vous êtes prêt à partir.
phil294

105

Il n'est pas nécessaire d'utiliser indexOfou splice. Cependant, il fonctionne mieux si vous ne souhaitez supprimer qu'une seule occurrence d'un élément.

Rechercher et déplacer (déplacer):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

Utilisation indexOfet splice(index de):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

Utiliser uniquement splice(épissure):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

Temps d'exécution sur nodejs pour tableau avec 1000 éléments (moyenne sur 10000 exécutions):

indexof est environ 10 fois plus lent que déplacer . Même s'il est amélioré en supprimant l'appel à indexOfin splice, il est bien pire que déplacer .

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms

5
On dirait que la méthode «move» présentée ici devrait fonctionner dans tous les navigateurs, et évite également de créer un tableau supplémentaire; la plupart des autres solutions ici ont un ou les deux de ces problèmes. Je pense que celui-ci mérite beaucoup plus de votes, même s'il ne semble pas aussi "joli".
sockmonk

73

Cela fournit un prédicat au lieu d'une valeur.

REMARQUE: il mettra à jour le tableau donné et renverra les lignes affectées.

Usage

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

Définition

var helper = {

    // Remove and return the first occurrence

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences

    remove: function(array, predicate) {
        var removed = [];

        for (var i = 0; i < array.length;) {

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }
            i++;
        }
        return removed;
    }
};

Je ne sais pas si vous avez besoin de la vérification -1 (i> -1). De plus, je pense que ces fonctions agissent plus comme un filtre que comme une suppression. Si vous passez row.id === 5, il en résultera un tableau avec seulement l'id 5, donc il fait le contraire de remove. Cela aurait l'air bien dans ES2015: var result = ArrayHelper.remove (myArray, row => row.id === 5);
Ce qui serait cool du

@WhatWouldBeCool cette fonction modifie le tableau d'origine et renvoie l'élément supprimé au lieu de copier le résultat dans un nouveau tableau
amd

68

Vous pouvez le faire facilement avec la méthode de filtrage :

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));

Cela supprime tous les éléments du tableau et fonctionne également plus rapidement qu'une combinaison de sliceet indexOf.


3
Avez-vous une source sur le fait que c'est plus rapide?
user3711421

2
Belle solution. Mais comme vous le signalez, mais important de rendre chauve, cela ne produit pas le même résultat que slice et indexOf car il supprimera toutes les occurrences de 1
user3711421

1
@ user3711421 c'est parce que juste slice et indexOf ne fait pas ce qu'il veut "supprimer un élément spécifique". Il supprime l'élément une seule fois, cela supprime un élément spécifique, peu importe le nombre d'entre eux
Salvador Dali

66

John Resig a publié une bonne mise en œuvre :

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Si vous ne souhaitez pas étendre un objet global, vous pouvez faire quelque chose comme ceci, à la place:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

Mais la raison principale pour laquelle je poste ceci est de mettre en garde les utilisateurs contre l'implémentation alternative suggérée dans les commentaires sur cette page (14 décembre 2007):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

Cela semble bien fonctionner au début, mais grâce à un processus douloureux, j'ai découvert qu'il échouait en essayant de supprimer l'avant-dernier élément d'un tableau. Par exemple, si vous avez un tableau à 10 éléments et que vous essayez de supprimer le 9e élément avec ceci:

myArray.remove(8);

Vous vous retrouvez avec un tableau à 8 éléments. Je ne sais pas pourquoi, mais j'ai confirmé que l'implémentation d'origine de John n'a pas ce problème.


Je viens d'apprendre à la dure pourquoi c'est une bonne idée de Object.prototype.hasOwnPropertytoujours utiliser ¬¬
Davi Fiamenghi

64

Underscore.js peut être utilisé pour résoudre des problèmes avec plusieurs navigateurs. Il utilise des méthodes de navigateur intégrées si elles sont présentes. S'ils sont absents comme dans le cas des anciennes versions d'Internet Explorer, il utilise ses propres méthodes personnalisées.

Un exemple simple pour supprimer des éléments du tableau (du site Web):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

bien qu'élégant et concis, OP mentionne clairement le noyau JS uniquement
EigenFool

64

Vous pouvez utiliser ES6. Par exemple, pour supprimer la valeur «3» dans ce cas:

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');
console.log(newArray);

Production :

["1", "2", "4", "5", "6"]

4
Cette réponse est intéressante car elle crée une copie du tableau d'origine, au lieu de modifier directement l'original.
Claudio Holanda

Remarque: Array.prototype.filter est ECMAScript 5.1 (pas IE8). pour des solutions plus spécifiques: stackoverflow.com/a/54390552/8958729
Chang

54

Si vous souhaitez supprimer un nouveau tableau avec les positions supprimées, vous pouvez toujours supprimer l'élément spécifique et filtrer le tableau. Il pourrait avoir besoin d'une extension de l' objet tableau pour les navigateurs qui n'implémentent pas la méthode de filtrage, mais à long terme, c'est plus facile puisque tout ce que vous faites est le suivant:

var my_array = [1, 2, 3, 4, 5, 6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

Il devrait s'afficher [1, 2, 3, 4, 6].


45

Consultez ce code. Il fonctionne dans tous les principaux navigateurs .

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

Appelez cette fonction

remove_item(array,value);

4
@RolandIllig Sauf l'utilisation d'une for inboucle et le fait que le script ait pu s'arrêter plus tôt, en renvoyant directement le résultat de la boucle. Les votes positifs sont raisonnables;)
yckart

1
Il s'agit d'une excellente approche pour les petits tableaux. Il fonctionne dans tous les navigateurs, utilise un code minimal et intuitif, et sans cadres, cales ou polyfills supplémentaires complexes.
Beejor

Je devrais également réitérer le commentaire de yckart qui for( i = 0; i < arr.length; i++ )serait une meilleure approche car il préserve les indices exacts par rapport à l'ordre dans lequel le navigateur décide de stocker les éléments (avec for in). Cela vous permet également d'obtenir l'index du tableau d'une valeur si vous en avez besoin.
Beejor

41

Vous pouvez utiliser lodash _.pull (tableau muté ), _.pullAt (tableau muté ) ou _ . Sans (ne mute pas le tableau),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']

2
Ce n'est pas le noyau JS comme l'OP l'a demandé, n'est-ce pas?
un utilisateur non descriptif du

12
@ some-non-descript-user Vous avez raison. Mais beaucoup d'utilisateurs comme moi viennent ici à la recherche d'une réponse générale, pas seulement pour l'OP uniquement.
Chun Yang

@ChunYang Vous avez absolument raison. J'utilise déjà lodash, pourquoi ne pas l'utiliser si cela fait gagner du temps.
int-i

38

ES6 & sans mutation: (octobre 2016)

const removeByIndex = (list, index) =>
      [
        ...list.slice(0, index),
        ...list.slice(index + 1)
      ];
         
output = removeByIndex([33,22,11,44],1) //=> [33,11,44]
      
console.log(output)


Pourquoi ne pas simplement utiliser filteralors? array.filter((_, index) => index !== removedIndex);.
user4642212

@ user4642212 vous avez raison! aussi, j'ai aimé le souligné du style Golang
Abdennour TOUMI

36

La suppression d'un élément / chaîne particulier d'un tableau peut être effectuée dans une seule ligne:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

où:

theArray : le tableau dont vous souhaitez supprimer quelque chose de particulier

stringToRemoveFromArray : la chaîne que vous souhaitez supprimer et 1 est la quantité d'éléments que vous souhaitez supprimer.

REMARQUE : Si "stringToRemoveFromArray" ne se trouve pas dans votre tableau, cela supprimera le dernier élément du tableau.

C'est toujours une bonne pratique de vérifier si l'élément existe dans votre tableau avant de le supprimer.

if (theArray.indexOf("stringToRemoveFromArray") >= 0){
   theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}

Si vous avez accès à des versions plus récentes d'Ecmascript sur les ordinateurs de votre client (AVERTISSEMENT, peut ne pas fonctionner sur les stations plus anciennes):

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');

Où «3» est la valeur que vous souhaitez supprimer du tableau. Le tableau deviendrait alors:['1','2','4','5','6']


C'est la réponse qui a fonctionné pour moi lorsque j'ai essayé de mettre à jour un tableau basé sur le basculement des boutons radio.
jdavid05

4
Attention, s'il "stringToRemoveFromArray"ne se trouve pas dans votre tableau, cela supprimera le dernier élément du tableau.
Fusion

35

Voici quelques façons de supprimer un élément d'un tableau à l'aide de JavaScript .

Toutes les méthodes décrites ne modifient pas le tableau d'origine et en créent plutôt un nouveau.

Si vous connaissez l'index d'un article

Supposons que vous ayez un tableau et que vous souhaitiez supprimer un élément en position i.

Une méthode consiste à utiliser slice():

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i).concat(items.slice(i+1, items.length))

console.log(filteredItems)

slice()crée un nouveau tableau avec les index qu'il reçoit. Nous créons simplement un nouveau tableau, du début à l'index que nous voulons supprimer, et concaténons un autre tableau de la première position suivant celle que nous avons supprimée à la fin du tableau.

Si vous connaissez la valeur

Dans ce cas, une bonne option est d'utiliser filter(), qui offre une approche plus déclarative :

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

Cela utilise les fonctions fléchées ES6. Vous pouvez utiliser les fonctions traditionnelles pour prendre en charge les anciens navigateurs:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

ou vous pouvez utiliser Babel et transpiler le code ES6 vers ES5 pour le rendre plus digeste pour les anciens navigateurs, tout en écrivant du JavaScript moderne dans votre code.

Suppression de plusieurs éléments

Et si au lieu d'un seul élément, vous souhaitez supprimer plusieurs éléments?

Trouvons la solution la plus simple.

Par index

Vous pouvez simplement créer une fonction et supprimer des éléments en série:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

Par valeur

Vous pouvez rechercher une inclusion dans la fonction de rappel:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

Évitez de muter la matrice d'origine

splice()(à ne pas confondre avec slice()) mute le tableau d'origine et doit être évité.

(initialement publié sur https://flaviocopes.com/how-to-remove-item-from-array/ )


34

OK, par exemple, vous avez le tableau ci-dessous:

var num = [1, 2, 3, 4, 5];

Et nous voulons supprimer le numéro 4. Vous pouvez simplement utiliser le code ci-dessous:

num.splice(num.indexOf(4), 1); // num will be [1, 2, 3, 5];

Si vous réutilisez cette fonction, vous écrivez une fonction réutilisable qui sera attachée à la fonction de tableau natif comme ci-dessous:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1)
      return;
  this.splice(i, 1); // num.remove(5) === [1, 2, 3];
}

Mais que diriez-vous si vous avez le tableau ci-dessous à la place avec quelques [5] s dans le tableau?

var num = [5, 6, 5, 4, 5, 1, 5];

Nous avons besoin d'une boucle pour les vérifier tous, mais un moyen plus simple et plus efficace utilise les fonctions JavaScript intégrées, nous écrivons donc une fonction qui utilise un filtre comme ci-dessous à la place:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) // Return [1, 2, 3, 4, 6]

Il existe également des bibliothèques tierces qui vous aident à le faire, comme Lodash ou Underscore. Pour plus d'informations, consultez lodash _.pull, _.pullAt ou _.without.


Il y a une petite faute de frappe. Corrigez s'il vous plaît. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa

Veuillez ne pas augmenter les fonctions intégrées (attacher des fonctions à Array.prototype) en JavaScript. Ceci est largement considéré comme une mauvaise pratique.
aikeru

Je suis d'accord que ce n'est pas la meilleure chose à faire au monde, mais dans ce cas, comment pourriez-vous le transmettre à la fonction?
Alireza

Vous devriez vérifier l'index. Si index = -1, splice (-1,1) supprimera le dernier élément
Richard Chan

29

Je suis assez nouveau sur JavaScript et j'avais besoin de cette fonctionnalité. J'ai simplement écrit ceci:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

Puis quand je veux l'utiliser:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

Sortie - Comme prévu. ["item1", "item1"]

Vous pouvez avoir des besoins différents des miens, vous pouvez donc facilement les modifier pour les adapter. J'espère que ça aidera quelqu'un.


1
Cela va avoir un comportement terrible si votre tableau est vraiment long et qu'il contient plusieurs instances de l'élément. La méthode indexOf du tableau commencera au début à chaque fois, donc votre coût sera O (n ^ 2).
Zag


27

Si vous avez des objets complexes dans le tableau, vous pouvez utiliser des filtres? Dans les situations où $ .inArray ou array.splice n'est pas aussi facile à utiliser. Surtout si les objets sont peut-être peu profonds dans le tableau.

Par exemple, si vous avez un objet avec un champ Id et que vous souhaitez que l'objet soit supprimé d'un tableau:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

C'est comme ça que j'aime le faire. En utilisant une fonction de flèche, il peut s'agir d'une ligne unique. Je suis curieux de performance. Ne vaut rien non plus que cela remplace le tableau. Tout code avec une référence à l' ancien tableau ne remarquera pas le changement.
joeytwiddle

27

Je veux répondre sur la base d' ECMAScript 6 . Supposons que vous ayez un tableau comme ci-dessous:

let arr = [1,2,3,4];

Si vous souhaitez supprimer à un index spécial comme 2, écrivez le code ci-dessous:

arr.splice(2, 1); //=> arr became [1,2,4]

Mais si vous souhaitez supprimer un élément spécial comme 3et que vous ne connaissez pas son index, faites comme ci-dessous:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

Astuce : veuillez utiliser une fonction de flèche pour le rappel du filtre, sauf si vous obtiendrez un tableau vide.


25

Mise à jour: cette méthode est recommandée uniquement si vous ne pouvez pas utiliser ECMAScript 2015 (anciennement ES6). Si vous pouvez l'utiliser, d'autres réponses ici fournissent des implémentations beaucoup plus soignées.


Cet élément résoudra votre problème et supprimera également toutes les occurrences de l'argument au lieu de seulement 1 (ou une valeur spécifiée).

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

    for(var i = 0; i < this.length; i++){

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

Usage:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]

25

Performance

Aujourd'hui (2019-12-09), je réalise des tests de performances sur macOS v10.13.6 (High Sierra) pour les solutions choisies. Je montredelete (A), mais je ne l'utilise pas en comparaison avec d'autres méthodes, car cela laisse un espace vide dans le tableau.

Les conclusions

  • la solution la plus rapide est array.splice(C) (sauf Safari pour les petits tableaux où il a la deuxième fois)
  • pour les grands tableaux, array.slice+splice(H) est la solution immuable la plus rapide pour Firefox et Safari;Array.from(B) est le plus rapide dans Chrome
  • les solutions mutables sont généralement 1,5x à 6x plus rapides qu'immuables
  • pour les petites tables sur Safari, étonnamment la solution mutable (C) est plus lente que la solution immuable (G)

Détails

Dans les tests, je supprime l'élément central du tableau de différentes manières. Les solutions A, C sont en place. Les B, D, E, F, G, H solutions sont immuables.

Résultats pour tableau avec 10 éléments

Entrez la description de l'image ici

Dans Chrome, le array.splice(C) est la solution en place la plus rapide. Le array.filter(D) est la solution immuable la plus rapide. Le plus lent est array.slice(F). Vous pouvez effectuer le test sur votre machine ici .

Résultats pour tableau avec 1.000.000 éléments

Entrez la description de l'image ici

Dans Chrome, le array.splice(C) est la solution en place la plus rapide (le delete(C) est similaire rapidement - mais il a laissé un emplacement vide dans le tableau (il n'effectue donc pas de `` suppression complète '')). Le array.slice-splice(H) est la solution immuable la plus rapide. Le plus lent est array.filter(D et E). Vous pouvez effectuer le test sur votre machine ici .

Comparaison pour les navigateurs: Chrome v78.0.0, Safari v13.0.4 et Firefox v71.0.0

Entrez la description de l'image ici


24

Vous ne devez jamais muter votre tableau. Comme c'est contre le modèle de programmation fonctionnelle. Vous pouvez créer un nouveau tableau sans référencer le tableau dont vous souhaitez modifier les données à l'aide de la méthode ECMAScript 6 filter;

var myArray = [1, 2, 3, 4, 5, 6];

Supposons que vous souhaitiez supprimer 5du tableau, vous pouvez simplement le faire comme ceci:

myArray = myArray.filter(value => value !== 5);

Cela vous donnera un nouveau tableau sans la valeur que vous vouliez supprimer. Le résultat sera donc:

 [1, 2, 3, 4, 6]; // 5 has been removed from this array

Pour une meilleure compréhension, vous pouvez lire la documentation MDN sur Array.filter .


21

Une approche plus moderne, ECMAScript 2015 (anciennement Harmony ou ES 6). Donné:

const items = [1, 2, 3, 4];
const index = 2;

Alors:

items.filter((x, i) => i !== index);

Rendement:

[1, 2, 4]

Vous pouvez utiliser Babel et un service polyfill pour vous assurer que cela est bien pris en charge sur tous les navigateurs.


4
Notez que .filterrenvoie un nouveau tableau, ce qui n'est pas exactement la même chose que la suppression de l'élément du même tableau. L'avantage de cette approche est que vous pouvez enchaîner des méthodes de tableau. par exemple:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot

Génial, si j'ai 600k éléments dans le tableau et que je veux supprimer les premiers 50k, pouvez-vous imaginer cette lenteur? Ce n'est pas une solution, il faut une fonction qui supprime simplement les éléments et ne renvoie rien.
dev1223

@Seraph Pour cela, vous voudrez probablement utiliser spliceou slice.
bjfletcher

@bjfletcher C'est encore mieux, en cours de suppression, allouez simplement 50K éléments et jetez-les quelque part. (avec tranche 550K éléments, mais sans les jeter de la fenêtre).
dev1223

Je préfère la réponse de bjfletcher, qui pourrait être aussi courte que items= items.filter(x=>x!=3). En outre, l'OP n'a indiqué aucune exigence pour un grand ensemble de données.
runun

21

Vous avez 1 à 9 dans le tableau et vous souhaitez supprimer 5. Utilisez le code ci-dessous:

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);


Si vous souhaitez plusieurs valeurs. Exemple: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 1,7 and 8 removed", newNumberArray);


Si vous souhaitez supprimer une valeur de tableau dans un tableau. Exemple: [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

Comprend le navigateur pris en charge est un lien .


19

Je sais qu'il y a déjà beaucoup de réponses, mais beaucoup d'entre elles semblent trop compliquer le problème. Voici un moyen simple et récursif de supprimer toutes les instances d'une clé - s'appelle soi jusqu'à ce que l'index ne soit pas trouvé. Oui, cela ne fonctionne que dans les navigateurs indexOf, mais c'est simple et peut être facilement rempli.

Fonction autonome

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

Méthode prototype

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}

Juste une note, 1 mise en garde avec cette méthode est le potentiel de débordements de pile. À moins que vous ne travailliez avec des tableaux massifs, vous ne devriez pas avoir de problème.
wharding28

Mais pourquoi un retour au milieu? Il s'agit en fait d'une déclaration goto.
Peter Mortensen

18

Vous pouvez faire une boucle arrière pour vous assurer de ne pas visser les index, s'il y a plusieurs instances de l'élément.

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

Démo en direct

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.