223

I have been trying several approaches on how to find an object in an array, where ID = var, and if found, remove the object from the array and return the new array of objects.

Data:

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

I'm able to search the array using jQuery $grep;

var id = 88;

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

But how can I delete the entire object when id == 88, and return data like the following?

Data:

[
    {"id":"99", "name":"Have fun boys and girls"},
    {"id":"108", "name":"You are awesome!"}
]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tom
  • 3,717
  • 5
  • 26
  • 28
  • What about using `slice` function and a little `for` loop? – Ahmed Hamdy Feb 09 '14 at 13:57
  • 1
    Sure, but, reason I wrote this question, is because I am stuck ;) any snippets? – Tom Feb 09 '14 at 13:58
  • Check this post http://stackoverflow.com/questions/10827894/how-do-i-slice-an-array-from-an-array-of-object-literals – Ahmed Hamdy Feb 09 '14 at 14:01
  • The title and question text seem to conflict... suggesting two entirely different approaches: **A.** remove items from an array versus **B.** create a new, filtered array. – canon Dec 20 '16 at 19:54
  • Does this answer your question? [Remove array element based on object property](https://stackoverflow.com/questions/15287865/remove-array-element-based-on-object-property) – Heretic Monkey May 16 '22 at 14:47

14 Answers14

287

Here is a solution if you are not using jQuery:

myArray = myArray.filter(function( obj ) {
  return obj.id !== id;
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adam Boostani
  • 5,999
  • 9
  • 38
  • 44
171

I can grep the array for the id, but how can I delete the entire object where id == 88

Simply filter by the opposite predicate:

var data = $.grep(data, function(e){ 
     return e.id != id; 
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 13
    This answer provides the most concise and idiomatic solution for jQuery – Bryan Feb 09 '14 at 14:03
  • 1
    In you case where you want to delete all items with id=something is fine ... but be careful when using $.grep as it searches the full array and for long arrays it is not efficient. Sometimes you just need to check if the element exists inside the array by a given ID, then is better to use another iteration method ;) – julianox Dec 04 '14 at 04:03
  • 1
    This doesn't remove that object from list – Arun Sivan Aug 06 '17 at 09:39
  • @ArunSivan Yes, it overwrites the `data` variable with a new list, which is usually a much better idea. – Bergi Aug 06 '17 at 12:46
  • What if he intended to remove the object from list, so that he can use the new array some where else..like `myArray.slice(index,1);` – Arun Sivan Aug 06 '17 at 13:37
  • 1
    @ArunSivan `slice` doesn't remove anything either. Not sure what you're getting at. If you have a specific problem yourself, you might want to [ask a new question](https://stackoverflow.com/questions/ask). – Bergi Aug 06 '17 at 13:41
  • @Bergi Hi. If I have an array of ids and I want to remove them then what should I be doing? Thanks in advance. – Vibhav Chaddha Jun 07 '19 at 11:57
  • @Learner Filter for the array to not [contain](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) the respective id. – Bergi Jun 07 '19 at 12:01
  • @Bergi Extremely Sorry but I didn't get you. Instead of a single id = 88, if I have an array like id = [88, 99] then how can I remove those 2 objects and get only "{"id":"108","name":"You are awesome!"}" in the data. – Vibhav Chaddha Jun 07 '19 at 12:19
  • 1
    @Learner `data.filter(e => !ids.includes(e.id))` – Bergi Jun 07 '19 at 13:07
  • @BergiThanks for the help. – Vibhav Chaddha Jun 07 '19 at 13:14
107

You can simplify this, and there isn't really any need for using jQuery here.

var id = 88;

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

Just iterate through the list, find the matching id, splice, and then break to exit your loop.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bryan
  • 6,682
  • 2
  • 17
  • 21
  • 20
    +1, but you should mention that this does delete only the first item which matches. – Bergi Feb 09 '14 at 14:02
  • 9
    ... And if you need to delete each matched items, loop on reverse order with `i=data.length; i > 0; i--` and don't use `break`. – Jeremy Belolo Sep 28 '16 at 11:27
  • 5
    `i = data.length` will break any `data[i]`, it should be something like `i=data.length -1 ; i > -1; i--` – distante Nov 28 '16 at 10:34
43

There's a new method to do this in ES6/2015 using findIndex and the array spread operator:

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

You can turn it into a function for later reuse like this:

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

This way, you can remove items by different keys using one method (and if there's no object that meets the criteria, you get original array returned):

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

Or you can put it on your Array.prototype:

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

And use it this way:

const newData = data.remove("id", "88");
const newData2 = data.remove("name", "You are awesome!");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zorza
  • 2,814
  • 3
  • 27
  • 41
13

Native ES6 solution:

const pos = data.findIndex(el => el.id === ID_TO_REMOVE);
if (pos >= 0)
    data.splice(pos, 1);

If you know that the element is in the array for sure:

data.splice(data.findIndex(el => el.id === ID_TO_REMOVE), 1);

Prototype:

Array.prototype.removeByProp = function(prop,val) {
    const pos = this.findIndex(x => x[prop] === val);
    if (pos >= 0)
        return this.splice(pos, 1);
};

// usage:
ar.removeByProp('id', ID_TO_REMOVE);

http://jsfiddle.net/oriadam/72kgprw5/

Note: this removes the item in-place. If you need a new array, use filter as mentioned in previous answers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
oriadam
  • 7,747
  • 2
  • 50
  • 48
12
var items = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

If you are using jQuery, use jQuery.grep like this:

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

Using ES5 Array.prototype.filter:

items = items.filter(function(item) { 
  return item.id !== '88'; 
});
// items => [{ id: "99" }, { id: "108" }]
nekman
  • 1,919
  • 2
  • 15
  • 26
9

Assuming that ids are unique and you'll only have to remove the one element splice should do the trick:

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
  • 16,490
  • 14
  • 62
  • 74
  • You have the elements in your callback function backwards. It should be `each(data,function(idx,ele)`. I'll bill you later for the 30 min I wasted figuring that out :) – CSharper Nov 10 '15 at 16:58
  • Oops. The least I can do in that case is update my answer. I feel really bad about your wasted 30 minutes of life. – James Hibbard Nov 10 '15 at 21:09
6

I agree with the previous answers. A simple way if you want to find an object by id and remove it is simply like the below code:

var obj = JSON.parse(data);
var newObj = obj.filter(item => item.Id != 88);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MJ X
  • 8,506
  • 12
  • 74
  • 99
6
const data = [
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
];

Here we get the index of the object whose value of the id is "88"

const index = data.findIndex(item => item.id === "88");
console.log(index); // 0

We use splice function to remove the specified object from data array

data.splice(index,1);
console.log(data); // [{"id":"99","name":"Have fun boys and girls"},{"id":"108","name":"You are awesome!"}]
Sandeep Mukherjee
  • 673
  • 1
  • 9
  • 17
4

Maybe you are looking for $.grep() function:

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
});
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
3
Array.prototype.removeAt = function(id) {
    for (var item in this) {
        if (this[item].id == id) {
            this.splice(item, 1);
            return true;
        }
    }
    return false;
}

This should do the trick, jsfiddle

casraf
  • 21,085
  • 9
  • 56
  • 91
3

sift is a powerful collection filter for operations like this and much more advanced ones. It works client side in the browser or server side 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);

It supports filters like $in, $nin, $exists, $gte, $gt, $lte, $lt, $eq, $ne, $mod, $all, $and, $or, $nor, $not, $size, $type, and $regex, and strives to be API-compatible with MongoDB collection filtering.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Redsandro
  • 11,060
  • 13
  • 76
  • 106
  • Why no upwotes? If this thing is properly writen and have no terrible bugs it should beextremely usefull. – Max Yari Nov 03 '15 at 21:01
0

Make sure you coerce the object id to an integer if you test for strict equality:

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

Demo

Andy
  • 61,948
  • 13
  • 68
  • 95
0

If you are using Underscore.js, it is easy to remove an object based on a key.

Example:

  var temp1=[{id:1,name:"safeer"},  // Temporary 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];
  });
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mohammed Safeer
  • 20,751
  • 8
  • 75
  • 78