Rimuovi l'elemento array in base alla proprietà dell'oggetto


271

Ho una serie di oggetti in questo modo:

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

Come posso rimuoverne uno specifico in base alla sua proprietà?

ad es. come rimuovere l'oggetto array con 'money' come proprietà field?

Risposte:


384

Una possibilità:

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

Si noti che filtercrea un nuovo array. Tutte le altre variabili che si riferiscono all'array originale non otterrebbero i dati filtrati sebbene si aggiorni la variabile originale myArraycon il nuovo riferimento. Usare con cautela.


6
Nota che filter()è disponibile solo per Internet Explorer 9+
jessegavin,

@jessegavin davvero. Avrei dovuto menzionare che ci sono molte buone librerie di shim es5 disponibili, che imitano la funzionalità (nel caso in cui si desideri supportare i browser legacy)
jAndy

3
filter()crea un nuovo array, il che va bene se sei in grado di riassegnare la variabile e sapere che non ci sono altre aree di codice che hanno riferimenti ad essa. Questo non funzionerà se è necessario modificare l'oggetto array originale.
Brian Glick,

2
Che cosa succede se l'array è una struttura ad albero ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "change test 23"}]}] e desidero eliminare id: 23
forgottofly,

@forgottofly buon punto - la risposta funziona solo per casi limitati. Hai trovato la risposta alla tua domanda?
JackTheKnife,

88

Scorrere l'array e spliceindividuare quelli che non si desidera. Per un utilizzo più semplice, scorrere all'indietro in modo da non dover tenere conto della natura live dell'array:

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

3
cosa intendi per natura live dell'array? @Neit the Dark Absol
sisimh

29
@sisimh significa che se si esegue l'iterazione in avanti di un array usando la sua lunghezza come parte della logica di iterazione e la sua lunghezza cambia perché ha elementi rimossi o aggiunti, si può finire per correre fuori dalla fine dell'array o non fare l'operazione per ogni elemento nella matrice. Andare all'indietro rende molto meno probabile poiché lavora verso un indice 0 statico piuttosto che una lunghezza mobile.
Klors,

2
Che cosa succede se l'array è una struttura ad albero ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "change test 23"}]}] e desidero eliminare id: 23
forgottofly,

Ovviamente, ma se ti aspetti solo di rimuovere un singolo elemento univoco, puoi lanciare un'interruzione nell'istruzione 'if' per le prestazioni in modo che il ciclo non passi inutilmente sul resto dell'array.
Patrick Borkowicz,

@Klors Grazie per aver spiegato. È bene leggere sempre l'array all'indietro come nella risposta?
Kittu,

38

Supponiamo che tu voglia rimuovere il secondo oggetto dalla sua proprietà field.

Con ES6 è facile come questo.

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

7
Ho provato questo, ma invece di "rimuovere" il terzo elemento dall'array di OP, il tuo codice è "filtrato" e visualizza solo il terzo elemento.
Compaq LE2202x

1
@ CompaqLE2202x 2 anni dopo probabilmente è già ovvio per te, ma per i futuri sviluppatori: splicecambia l'array originale, quindi il valore che ottieni è l'elemento che è stato rimosso, ma se lo guarderai successivamente myArraymancherà.
David Mulder,

17

È possibile utilizzare findIndex di lodash per ottenere l'indice dell'elemento specifico e quindi giuntarlo usando.

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

Aggiornare

Puoi anche usare findIndex () di ES6

Il metodo findIndex () restituisce l'indice del primo elemento dell'array che soddisfa la funzione di test fornita. Altrimenti viene restituito -1.

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

Qual è l'array è una struttura ad albero?
dimenticato il

@forgottofly struttura ad albero? Penso che myArrayqui sia una serie di oggetti.
Sridhar,

4
Che cosa succede se l'array è una struttura ad albero var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "change test 23"}]}] e desidero eliminare id: 23
forgottofly,

9

Ecco un'altra opzione che utilizza jQuery grep. Passa truecome terzo parametro per assicurarti che grep rimuova gli elementi che corrispondono alla tua funzione.

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

Se stai già utilizzando jQuery, non è richiesto alcuno spessore, il che potrebbe essere utile al contrario dell'uso Array.filter.


8

In ES6, solo una riga.

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

:)


3

Di seguito è riportato il codice se non si utilizza jQuery. dimostrazione

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);

Puoi anche usare la libreria di sottolineatura che ha molte funzioni.

Underscore è una libreria di utilità-cintura per JavaScript che fornisce molto supporto di programmazione funzionale


5
Questo è un esempio molto pericoloso da lasciare sul web ... funziona con i dati di esempio, ma non con nient'altro. splice (i) significa che rimuoverà tutti gli elementi dell'array a partire da e dopo la prima istanza in cui il valore è denaro, che non soddisfa affatto il requisito di op. Se passassimo a splice (i, 1) sarebbe comunque errato perché non valuterebbe l'elemento sequenziale successivo (dovresti decrementare anche i) Ecco perché dovresti elaborare le operazioni di rimozione in array all'indietro, in modo da rimuovere un l'oggetto non altera gli indici dei prossimi oggetti da elaborare
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'elemento è un oggetto nella matrice. Il terzo parametro truesignifica che restituirà una matrice di elementi che non riesce la logica della funzione, che falsesignifica che restituirà una matrice di elementi che non riesce la logica della funzione.


3

Sulla base di alcuni commenti sopra riportati di seguito è riportato il codice su come rimuovere un oggetto in base al nome e al valore della chiave

 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

Utilizzando la libreria 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 soluzione di jAndy è probabilmente la migliore, ma se non puoi fare affidamento sul filtro potresti fare qualcosa del tipo:

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
Perché non potrei fare affidamento su filter ()?
imperium2335

2
Perché fa parte di JavaScript 1.6, che non è supportato da IE8 e dai browser precedenti o precedenti.
Rob M.

-1

Utilizzando la libreria lodash è semplice come questo

_.remove(myArray , { field: 'money' });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.