Supprimer l'élément de tableau en fonction de la propriété d'objet


271

J'ai un tableau d'objets comme ça:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

Comment en supprimer un en fonction de sa propriété?

Par exemple, comment supprimer l'objet tableau avec «argent» comme propriété de champ?

Réponses:


384

Une possibilité:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

Veuillez noter que filtercrée un nouveau tableau. Toute autre variable faisant référence au tableau d'origine n'obtiendrait pas les données filtrées bien que vous mettiez à jour votre variable d'origine myArrayavec la nouvelle référence. Utiliser avec précaution.


6
Notez que filter()n'est disponible que pour Internet Explorer 9+
jessegavin

@jessegavin en effet. J'aurais dû mentionner qu'il y a beaucoup de bonnes bibliothèques de shims es5 disponibles, qui imitent la fonctionnalité (juste au cas où vous voudriez prendre en charge les navigateurs hérités)
jAndy

3
filter()crée un nouveau tableau, ce qui est bien si vous êtes en mesure de réaffecter la variable et de savoir qu'il n'y a pas d'autres zones de code qui y font référence. Cela ne fonctionnera pas si vous devez spécifiquement modifier l'objet de tableau d'origine.
Brian Glick

2
Que faire si le tableau est une structure arborescente ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "changé le test 23"}]}] et je veux supprimer id: 23
forgottofly le

@forgottofly bon point - la réponse ne fonctionne que pour des cas limités. Avez-vous trouvé la réponse à votre question?
JackTheKnife

88

Parcourez le tableau et splicesortez ceux que vous ne voulez pas. Pour une utilisation plus facile, itérez en arrière afin de ne pas avoir à prendre en compte la nature en direct du tableau:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
que voulez-vous dire par la nature en direct du tableau? @Neit the Dark Absol
sisimh

29
@sisimh, il signifie que si vous parcourez un tableau en avant en utilisant sa longueur dans le cadre de la logique d'itération et que sa longueur change parce qu'il a des éléments supprimés ou ajoutés, vous pouvez finir par courir à la fin du tableau ou ne pas faire l'opération pour chaque élément du tableau. Revenir en arrière rend cela beaucoup moins probable car il travaille vers un index 0 statique plutôt que vers une longueur mobile.
Klors

2
Que faire si le tableau est une structure arborescente ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "changé le test 23"}]}] et je veux supprimer id: 23
forgottofly le

Un peu évident, mais si vous vous attendez à supprimer un seul élément unique, vous pouvez jeter une coupure dans l'instruction 'if' pour les performances afin que la boucle n'itère pas inutilement sur le reste du tableau.
Patrick Borkowicz

@Klors Merci d'avoir expliqué. Est-il bon de toujours lire le tableau à l'envers comme dans la réponse?
kittu

38

Supposons que vous souhaitiez supprimer le deuxième objet par sa propriété de champ.

Avec ES6, c'est aussi simple que cela.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

7
J'ai essayé mais au lieu de "supprimer" le 3ème élément du tableau OP, votre code "filtré" et n'affichait que le 3ème élément.
Compaq LE2202x

1
@ CompaqLE2202x 2 ans plus tard, c'est probablement déjà évident pour vous, mais pour les futurs développeurs: splicemodifie le tableau d'origine, donc la valeur que vous récupérez est l'élément qui a été supprimé, mais si vous le regardez ensuite, myArrayl'élément sera manquant.
David Mulder

17

Vous pouvez utiliser findIndex de lodash pour obtenir l'index de l'élément spécifique, puis l'épisser en l'utilisant.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Mettre à jour

Vous pouvez également utiliser findIndex () d' ES6

La méthode findIndex () renvoie l'index du premier élément du tableau qui satisfait la fonction de test fournie. Sinon, -1 est renvoyé.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Qu'est-ce que le tableau est une structure arborescente?
forgottofly

@forgottofly arborescence? Je pense que myArrayvoici un tableau d'objets.
Sridhar

4
Que faire si le tableau est une structure arborescente var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "changé le test 23"}]}] et je veux supprimer id: 23
forgottofly

9

Voici une autre option utilisant jQuery grep. Passez truele troisième paramètre pour vous assurer que grep supprime les éléments qui correspondent à votre fonction.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

Si vous utilisez déjà jQuery, aucun shim n'est requis, ce qui pourrait être utile par opposition à l'utilisation Array.filter.


8

Dans ES6, une seule ligne.

const arr = arr.filter(item => item.key !== "some value");

:)


3

Voici le code si vous n'utilisez pas jQuery. Démo

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

Vous pouvez également utiliser une bibliothèque de soulignements qui ont beaucoup de fonctions.

Underscore est une bibliothèque de ceinture utilitaire pour JavaScript qui fournit une grande partie du support de programmation fonctionnelle


5
C'est un exemple très dangereux à laisser sur le web ... cela fonctionne avec les données d'exemple, mais pas avec autre chose. splice (i) signifie qu'il supprimera tous les éléments du tableau à partir de et après la première instance où value est money, ce qui ne satisfait pas du tout à l'exigence op. Si nous passions à l'épissure (i, 1), ce serait toujours incorrect car il n'évaluerait pas l'élément séquentiel suivant (vous devrez également décrémenter i) .C'est pourquoi vous devez traiter les opérations de suppression dans les tableaux à l'envers, l'élément ne modifie pas les index des éléments suivants à traiter
Chris Schaller

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

L'élément est un objet du tableau. Le troisième paramètre truesignifie retournera un tableau d'éléments qui échoue à votre logique de fonction, falsesignifie retournera un tableau d'éléments qui échouera à votre logique de fonction.


3

Sur la base de certains commentaires ci-dessus, le code explique comment supprimer un objet en fonction d'un nom de clé et d'une valeur de clé

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

3

Utilisation de la bibliothèque lodash :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


1

La solution de jAndy est probablement la meilleure, mais si vous ne pouvez pas vous fier au filtre, vous pouvez faire quelque chose comme:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
Pourquoi ne pourrais-je pas compter sur filter ()?
imperium2335

2
Parce qu'il fait partie de JavaScript 1.6, qui n'est pas pris en charge par IE8 et les navigateurs inférieurs ou antérieurs.
Rob M.

-1

En utilisant la bibliothèque lodash, c'est aussi simple que cela

_.remove(myArray , { field: 'money' });
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.