Javascript sucht und entfernt ein Objekt im Array basierend auf dem Schlüsselwert

138

Ich habe verschiedene Ansätze versucht, um ein Objekt in einem Array zu finden, wobei ID = var. Wenn es gefunden wird, entfernen Sie das Objekt aus dem Array und geben Sie das neue Array von Objekten zurück.

Daten:

[
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
]

Ich kann das Array mit jQuery $ grep durchsuchen.

var id = 88;

var result = $.grep(data, function(e){ 
     return e.id == id; 
});

Aber wie kann ich das gesamte Objekt löschen, wenn id == 88, und Daten wie folgt zurückgeben:

Daten:

[
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
]
Tom
quelle
Was ist mit der sliceFunktion und einer kleinen forSchleife?
Ahmed Hamdy
1
Sicher, aber der Grund, warum ich diese Frage geschrieben habe, ist, dass ich feststecke;) irgendwelche Schnipsel?
Tom
Überprüfen Sie diesen Beitrag stackoverflow.com/questions/10827894/…
Ahmed Hamdy
Der Titel und der Fragetext scheinen in Konflikt zu stehen ... was zwei völlig unterschiedliche Ansätze nahe legt: A. Entfernen von Elementen aus einem Array im Vergleich zu B. Erstellen eines neuen, gefilterten Arrays.
Kanon

Antworten:

155

Ich kann das Array nach der ID durchsuchen, aber wie kann ich das gesamte Objekt löschen, wobei id == 88 ist?

Filtern Sie einfach nach dem entgegengesetzten Prädikat:

var data = $.grep(data, function(e){ 
     return e.id != id; 
});
Bergi
quelle
12
Diese Antwort bietet die prägnanteste und idiomatischste Lösung für jQuery
Bryan
1
In dem Fall, in dem Sie alle Elemente mit id = löschen möchten, ist etwas in Ordnung. Seien Sie jedoch vorsichtig, wenn Sie $ .grep verwenden, da das gesamte Array durchsucht wird und lange Arrays nicht effizient sind. Manchmal müssen Sie nur anhand einer bestimmten ID überprüfen, ob das Element im Array vorhanden ist. Dann ist es besser, eine andere Iterationsmethode zu verwenden;)
julianox
1
Dies entfernt dieses Objekt nicht von der Liste
Arun Sivan
1
@ArunSivan sliceentfernt auch nichts. Ich bin mir nicht sicher, worauf du hinaus willst. Wenn Sie selbst ein bestimmtes Problem haben, möchten Sie möglicherweise eine neue Frage stellen .
Bergi
1
@Learnerdata.filter(e => !ids.includes(e.id))
Bergi
150

Hier ist eine Lösung, wenn Sie jquery nicht verwenden:

myArray = myArray.filter(function( obj ) {
  return obj.id !== id;
});
Adam Boostani
quelle
2
Ist das besser als zu tun findIndex()und dann splice(index, 1)auf dem übergeordneten Array?
Alex
Spleiß mutiert das Ursprungsarray. Mit Filter haben Sie die Wahl.
Velop
13
Sie können dies auf eine einzelne Zeile reduzieren, indem Sie Folgendes verwenden: myArr = myArray.filter (obj => obj.id! == id);
DBrown
2
noch prägnanterarr = arr.filter( obj => obj.id !== id);
Omar
86

Sie können dies vereinfachen, und es besteht hier wirklich keine Notwendigkeit, jquery zu verwenden.

var id = 88;

for(var i = 0; i < data.length; i++) {
    if(data[i].id == id) {
        data.splice(i, 1);
        break;
    }
}

Durchlaufen Sie einfach die Liste, suchen Sie die passende ID, spleißen Sie und brechen Sie dann ab, um Ihre Schleife zu verlassen

Bryan
quelle
17
+1, aber Sie sollten erwähnen, dass dadurch nur das erste übereinstimmende Element gelöscht wird.
Bergi
6
... und wenn Sie alle übereinstimmenden Elemente löschen müssen, wiederholen Sie die Schleife in umgekehrter Reihenfolge mit i=data.length; i > 0; i--und verwenden Sie sie nicht break.
Jeremy Belolo
3
i = data.lengthwird brechen data[i], sollte es so etwas wie seini=data.length -1 ; i > -1; i--
distante
31

Es gibt eine neue Methode, um dies in ES6 / 2015 mit findIndex und dem Array-Spread-Operator zu tun:

const index = data.findIndex(obj => obj.id === id);
const newData = [
    ...data.slice(0, index),
    ...data.slice(index + 1)
]

Sie können daraus eine Funktion für die spätere Wiederverwendung machen:

function remove(array, key, value) {
    const index = array.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...array.slice(0, index),
        ...array.slice(index + 1)
    ] : array;
}

Auf diese Weise können Sie Elemente mit einer Methode mit verschiedenen Schlüsseln entfernen (und wenn kein Objekt vorhanden ist, das die Kriterien erfüllt, wird das ursprüngliche Array zurückgegeben):

const newData = remove(data, "id", "88");
const newData2 = remove(data, "name", "You are awesome!");

Oder Sie können es auf Ihren Array.prototype setzen:

Array.prototype.remove = function (key, value) {
    const index = this.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...this.slice(0, index),
        ...this.slice(index + 1)
    ] : this;
};

Und benutze es so:

const newData = data.remove("id", "88");
const newData2 = data.remove("name", "You are awesome!");
Zorza
quelle
findIndex () ist wirklich toll! 👍
Danielcraigie
9

Unter der Annahme , dass IDs ist einzigartig und Sie werden nur das ein Element zu entfernen, splicesollte es tun:

var data = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
],
id = 88;

console.table(data);

$.each(data, function(i, el){
  if (this.id == id){
    data.splice(i, 1);
  }
});

console.table(data);
James Hibbard
quelle
Sie haben die Elemente in Ihrer Rückruffunktion rückwärts. Es sollte sein each(data,function(idx,ele). Ich werde dir später die 30 Minuten in Rechnung stellen, die ich damit verbracht habe, das herauszufinden :)
CSharper
Hoppla. In diesem Fall kann ich zumindest meine Antwort aktualisieren. Ich fühle mich wirklich schlecht wegen deiner verschwendeten 30 Minuten Leben.
James Hibbard
5
var items = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

Wenn Sie jQuery verwenden, verwenden Sie jQuery.grep wie folgt :

items = $.grep(items, function(item) { 
  return item.id !== '88';
});
// items => [{ id: "99" }, { id: "108" }]

Verwenden von ES5 Array.prototype.filter :

items = items.filter(function(item) { 
  return item.id !== '88'; 
});
// items => [{ id: "99" }, { id: "108" }]
nekman
quelle
1
Noooooo! Verwenden Sie die jQueryKarte nicht als Filter.
Bergi
1
Zustimmen! Ihre Lösung mit grep ist die richtige Lösung mit jQuery.
Nekman
4

Vielleicht suchen Sie nach $.grep()Funktion:

arr = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

id = 88;
arr = $.grep(arr, function(data, index) {
   return data.id != id
});
Rafael Garcia
quelle
3

siftist ein leistungsstarker Sammlungsfilter für Operationen wie diese und viel fortgeschrittenere. Es funktioniert clientseitig im Browser oder serverseitig in node.js.

var collection = [
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
];
var sifted = sift({id: {$not: 88}}, collection);

Es unterstützt Filter wie $in, $nin, $exists, $gte, $gt, $lte, $lt, $eq, $ne, $mod, $all, $and, $or, $nor, $not, $size, $type, und $regex, und ist bestrebt , API-kompatibel mit MongoDB Sammlung Filterung zu sein.

Redsandro
quelle
Warum keine Upwotes? Wenn dieses Ding richtig geschrieben ist und keine schrecklichen Fehler hat, sollte es äußerst nützlich sein.
Max Yari
2
Array.prototype.removeAt = function(id) {
    for (var item in this) {
        if (this[item].id == id) {
            this.splice(item, 1);
            return true;
        }
    }
    return false;
}

Dies sollte den Trick machen, jsfiddle

casraf
quelle
0

Stellen Sie sicher, dass Sie die Objekt-ID in eine Ganzzahl zwingen, wenn Sie auf strikte Gleichheit prüfen:

var result = $.grep(data, function(e, i) { 
  return +e.id !== id;
});

Demo

Andy
quelle
0

Wenn Sie js mit Unterstrich verwenden, ist es einfach, Objekte basierend auf dem Schlüssel zu entfernen. http://underscorejs.org . Beispiel:

  var temp1=[{id:1,name:"safeer"},  //temp array
             {id:2,name:"jon"},
             {id:3,name:"James"},
             {id:4,name:"deepak"},
             {id:5,name:"ajmal"}];

  var id = _.pluck(temp1,'id'); //get id array from temp1
  var ids=[2,5,10];             //ids to be removed
  var bool_ids=[];
  _.each(ids,function(val){
     bool_ids[val]=true;
  });
  _.filter(temp1,function(val){
     return !bool_ids[val.id];
  });
Mohammed Safeer
quelle