Entfernen Sie das Array-Element basierend auf der Objekteigenschaft

268

Ich habe eine Reihe von Objekten wie folgt:

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

Wie entferne ich eine bestimmte basierend auf ihrer Eigenschaft?

zB Wie würde ich das Array-Objekt mit 'money' als Feldeigenschaft entfernen?

imperium2335
quelle

Antworten:

381

Eine Möglichkeit:

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

Bitte beachten Sie, dass dadurch filterein neues Array erstellt wird. Alle anderen Variablen, die sich auf das ursprüngliche Array beziehen, erhalten die gefilterten Daten nicht, obwohl Sie Ihre ursprüngliche Variable myArraymit der neuen Referenz aktualisieren . Mit Vorsicht verwenden.

jAndy
quelle
6
Beachten Sie, dass filter()nur für Internet Explorer 9+
Jessegavin
@ Jessegavin in der Tat. Ich hätte erwähnen sollen, dass es viele gute es5-Shim- Bibliotheken gibt, die die Funktionalität nachahmen (nur für den Fall, dass Sie ältere Browser unterstützen möchten)
jAndy
3
filter()Erstellt ein neues Array. Dies ist in Ordnung, wenn Sie die Variable neu zuweisen können und wissen, dass es keine anderen Codebereiche gibt, auf die verwiesen wird. Dies funktioniert nicht, wenn Sie das ursprüngliche Array-Objekt speziell ändern müssen.
Brian Glick
2
Was ist, wenn das Array eine Baumstruktur ist? Ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "geänderter Test 23"}]}] und ich möchte id: 23 löschen
vergessen Sie den
@forgottofly guter Punkt - Antwort funktioniert nur für begrenzte Fälle. Haben Sie eine Antwort auf Ihre Frage gefunden?
JackTheKnife
87

Durchlaufen Sie das Array und splicediejenigen, die Sie nicht möchten. Iterieren Sie zur einfacheren Verwendung rückwärts, damit Sie die Live-Natur des Arrays nicht berücksichtigen müssen:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}
Niet the Dark Absol
quelle
3
Was meinst du mit der Live-Natur des Arrays? @Neit the Dark Absol
sisimh
29
@sisimh bedeutet, dass Sie, wenn Sie ein Array vorwärts iterieren, indem Sie dessen Länge als Teil der Iterationslogik verwenden und dessen Länge sich ändert, weil Elemente entfernt oder hinzugefügt wurden, möglicherweise am Ende des Arrays ablaufen oder die Operation für nicht ausführen jedes Element im Array. Wenn Sie rückwärts gehen, ist dies weniger wahrscheinlich, da es eher auf einen statischen 0-Index als auf eine sich bewegende Länge abzielt.
Klors
2
Was ist, wenn das Array eine Baumstruktur ist? Ar beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "geänderter Test 23"}]}] und ich möchte id: 23 löschen
vergessen Sie den
Ein bisschen offensichtlich, aber wenn Sie nur damit rechnen, ein einzelnes eindeutiges Element zu entfernen, können Sie eine Unterbrechung in die 'if'-Anweisung für die Leistung einfügen, damit die Schleife nicht unnötig über den Rest des Arrays iteriert.
Patrick Borkowicz
@Klors Danke für die Erklärung. Ist es gut, das Array immer rückwärts zu lesen, wie in der Antwort?
Kittu
37

Angenommen, Sie möchten das zweite Objekt anhand seiner Feldeigenschaft entfernen.

Mit ES6 ist das so einfach.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)
Peracek
quelle
6
Ich habe dies versucht, aber anstatt das dritte Element aus dem OP-Array zu "entfernen", hat Ihr Code "gefiltert" und nur das dritte Element angezeigt.
Compaq LE2202x
1
@ CompaqLE2202x 2 Jahre später ist es für Sie wahrscheinlich schon offensichtlich, aber für zukünftige Entwickler: splice das ursprüngliche Array, sodass der Wert, den Sie zurückerhalten, das Element ist, das entfernt wurde, aber wenn Sie sich myArraydas Element das nächste Mal ansehen , wird es fehlen.
David Mulder
16

Sie können den findIndex von lodash verwenden , um den Index des jeweiligen Elements abzurufen und dann damit zu verbinden.

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

Aktualisieren

Sie können auch findIndex () von ES6 verwenden.

Die Methode findIndex () gibt den Index des ersten Elements im Array zurück, das die bereitgestellte Testfunktion erfüllt. Andernfalls wird -1 zurückgegeben.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);
Sridhar
quelle
Was ist das Array ist eine Baumstruktur?
vergessen am
@ Forgottofly Baumstruktur? Ich denke myArrayhier ist eine Reihe von Objekten.
Sridhar
3
Was ist, wenn das Array eine Baumstruktur ist? Var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "geänderter Test 23"}]}] und ich möchte id: 23 löschen
vergessen am
9

Hier ist eine weitere Option mit jQuery grep. Übergeben Sie trueals dritten Parameter, um sicherzustellen, dass grep Elemente entfernt, die Ihrer Funktion entsprechen.

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

Wenn Sie jQuery bereits verwenden, ist kein Shim erforderlich, was im Gegensatz zur Verwendung nützlich sein kann Array.filter.

Freitag
quelle
7

In ES6 nur eine Zeile.

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

:) :)

Supun Kavinda
quelle
3

Im Folgenden finden Sie den Code, wenn Sie jQuery nicht verwenden. Demo

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

Sie können auch eine Unterstrichbibliothek verwenden, die viele Funktionen hat.

Underscore ist eine Utility-Belt-Bibliothek für JavaScript, die einen Großteil der Unterstützung für die funktionale Programmierung bietet

Umair Saleem
quelle
5
Dies ist ein sehr gefährliches Beispiel, das Sie im Web belassen sollten. Es funktioniert mit den Beispieldaten, aber nicht mit irgendetwas anderem. Spleiß (i) bedeutet, dass alle Elemente im Array ab und nach der ersten Instanz entfernt werden, in der Wert Geld ist, die die Anforderung von op überhaupt nicht erfüllen. Wenn wir zu splice (i, 1) wechseln würden, wäre dies immer noch falsch, da das nächste sequentielle Element nicht ausgewertet würde (Sie müssten auch i dekrementieren). Aus diesem Grund sollten Sie Entfernungsvorgänge in Arrays rückwärts verarbeiten, damit ein entfernt wird Artikel ändert nicht die Indizes der nächsten zu verarbeitenden Artikel
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

Element ist ein Objekt im Array. 3. Parameter truebedeutet, dass ein Array von Elementen zurückgegeben wird, bei denen Ihre Funktionslogik fehlschlägt. falseMittel bedeutet, dass ein Array von Elementen zurückgegeben wird, bei denen Ihre Funktionslogik nicht funktioniert.

Sandeep sandig
quelle
3

Nutzung der lodash- Bibliothek:

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
quelle
2

Basierend auf einigen Kommentaren oben ist der Code zum Entfernen eines Objekts basierend auf einem Schlüsselnamen und einem Schlüsselwert

 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
quelle
1

Die Lösung von jAndy ist wahrscheinlich die beste, aber wenn Sie sich nicht auf Filter verlassen können, können Sie Folgendes tun:

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.
quelle
1
Warum kann ich mich nicht auf filter () verlassen?
imperium2335
2
Weil es Teil von JavaScript 1.6 ist, das von IE8 und darunter oder älteren Browsern nicht unterstützt wird.
Rob M.
-1

Mit der lodash Bibliothek ist das ganz einfach

_.remove(myArray , { field: 'money' });
Gimnath
quelle