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?

imperium2335
la source

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.

jAndy
la source
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);
    }
}
Niet l'Absolu Noir
la source
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)
Peracek
la source
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);
Sridhar
la source
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.

vendredi
la source
8

Dans ES6, une seule ligne.

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

:)

Supun Kavinda
la source
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

Umair Saleem
la source
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.

Sandeep sable
la source
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);
JackTheKnife
la source
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>

Parth Raval
la source
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;
}
Rob M.
la source
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' });
Gimnath
la source