445

I have an array of objects like so:

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

How do I remove a specific one based on its property?

e.g. How would I remove the array object with 'money' as the field property?

0

12 Answers 12

600

One possibility:

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

Please note that filter creates a new array. Any other variables referring to the original array would not get the filtered data although you update your original variable myArray with the new reference. Use with caution.

Sign up to request clarification or add additional context in comments.

8 Comments

Note that filter() is only available for Internet Explorer 9+
@jessegavin indeed. I should have mentioned that there are plenty of good es5 shim libraries available, which mimic the functionality (just in case you want to support legacy browsers)
filter() creates a new array, which is fine if you're able to reassign the variable and know that there aren't other areas of code that have references to it. This won't work if you specifically need to modify the original array object.
What if the array is a tree structure ar beforeDeleteOperationArray=[ { "id": 3.1, "name": "test 3.1", "activityDetails": [ { "id": 22, "name": "test 3.1" }, { "id": 23, "name": "changed test 23" } ] } ] and I want to delete id:23
@forgottofly good point - answer works only for limited cases. Did you found answer to your question?
|
115

Say you want to remove the second object by its field property.

With ES6 it's as easy as this.

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

3 Comments

I tried this but instead of "removing" 3rd item from OP's array, your code "filtered" and displayed the 3rd item only.
@CompaqLE2202x 2 years later it's probably already obvious to you, but for future developers: splice changes the original array, so the value you get back is the item that was removed, but if you next look at myArray the item will be missing.
If the element is not found by findIndex, -1 is returned and the last element is removed by splice although it doesn't match the predicate.
113

Iterate through the array, and splice out the ones you don't want. For easier use, iterate backwards so you don't have to take into account the live nature of the array:

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

10 Comments

what do you mean by the live nature of the array ? @Neit the Dark Absol
@sisimh he means that if you iterate forwards over an array by using its length as part of the iteration logic and its length changes because it has elements removed or added you can end up running off the end of the array or not doing the operation for every item in the array. Going backwards makes that much less likely as it works towards a static 0 index rather than a moving length.
What if the array is a tree structure ar beforeDeleteOperationArray=[ { "id": 3.1, "name": "test 3.1", "activityDetails": [ { "id": 22, "name": "test 3.1" }, { "id": 23, "name": "changed test 23" } ] } ] and I want to delete id:23
Kinda obvious but if you are only expecting to remove a single unique element, you can throw a break into the 'if' statement for performance so the loop doesn't needlessly iterate over the rest of the array.
@Klors Thanks for explaining. Is it good to always read the array backwards as in the answer?
|
70

In ES6, just one line.

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

:)

1 Comment

Keep in mind that filter creates a new array.
27

You can use lodash's findIndex to get the index of the specific element and then splice using it.

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

Update

You can also use ES6's findIndex()

The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.

const itemToRemoveIndex = myArray.findIndex(function(item) {
  return item.field === 'money';
});

// proceed to remove an item only if it exists.
if(itemToRemoveIndex !== -1){
  myArray.splice(itemToRemoveIndex, 1);
}

6 Comments

What is the array is a tree structure?
@forgottofly tree structure? I think myArray here is an array of objects.
What if the array is a tree structure var beforeDeleteOperationArray=[ { "id": 3.1, "name": "test 3.1", "activityDetails": [ { "id": 22, "name": "test 3.1" }, { "id": 23, "name": "changed test 23" } ] } ] and I want to delete id:23
If the element is not found by findIndex (ES6 version), -1 is returned and the last element is removed by splice although it doesn't match the predicate.
@Yannic Nice catch. Thanks for pointing it out. Updated my answer for it.
|
19

We can remove the element based on the property using the below 2 approaches.

  1. Using filter method
testArray.filter(prop => prop.key !== 'Test Value')
  1. Using splice method. For this method we need to find the index of the propery.
const index = testArray.findIndex(prop => prop.key === 'Test Value')
testArray.splice(index,1)

1 Comment

the array filter() function does not modify the original array, therefore, your code needs a let newArray = testArray.filter(prop => prop.key !== 'Test Value').
9

Here's another option using jQuery grep. Pass true as the third parameter to ensure grep removes items that match your function.

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

If you're already using jQuery then no shim is required, which is could be useful as opposed to using Array.filter.

Comments

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 is an object in the array. 3rd parameter true means will return an array of elements which fails your function logic, false means will return an array of elements which fails your function logic.

Comments

2

Based on some comments above below is the code how to remove an object based on a key name and key value

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

Comments

2

Using the lodash library:

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>

Comments

1

jAndy's solution is probably best, but if you can't rely on filter you could do something like:

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

2 Comments

Why wouldn't I be able to rely on filter()?
Because it is part of JavaScript 1.6, which isn't supported by IE8 and below or older browsers.
0

Following is the code if you are not using jQuery. 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);

You can also use underscore library which have lots of function.

Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support

1 Comment

This is a very dangerous example to leave on the web... it works with the example data, but not with anything else. splice(i) means that it will remove all elements in the array starting at and after the first instance where value is money, which down not satisfy the requirement from op at all. If we changed to splice(i,1) it would still be incorrect because it would not evaluate the next sequential item (you would have to decrement i as well) This is why you should process remove operations in arrays backwards, so that removing an item doesn't alter the indexes of the next items to process

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.