Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove objects from array by object property

Tags:

javascript

People also ask

How do you remove an object from an array from a property?

To remove an object from an array by its value:Call the findIndex() method to get the index of the object in the array. Use the splice() method to remove the element at that index. The splice method changes the contents of the array by removing or replacing existing elements.

How do I remove an item from an array by value?

To remove an item from a given array by value, you need to get the index of that value by using the indexOf() function and then use the splice() function to remove the value from the array using its index.


I assume you used splice something like this?

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) !== -1) {
        arrayOfObjects.splice(i, 1);
    }
}

All you need to do to fix the bug is decrement i for the next time around, then (and looping backwards is also an option):

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) !== -1) {
        arrayOfObjects.splice(i, 1);
        i--;
    }
}

To avoid linear-time deletions, you can write array elements you want to keep over the array:

var end = 0;

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) === -1) {
        arrayOfObjects[end++] = obj;
    }
}

arrayOfObjects.length = end;

and to avoid linear-time lookups in a modern runtime, you can use a hash set:

const setToDelete = new Set(listToDelete);
let end = 0;

for (let i = 0; i < arrayOfObjects.length; i++) {
    const obj = arrayOfObjects[i];

    if (setToDelete.has(obj.id)) {
        arrayOfObjects[end++] = obj;
    }
}

arrayOfObjects.length = end;

which can be wrapped up in a nice function:

const filterInPlace = (array, predicate) => {
    let end = 0;

    for (let i = 0; i < array.length; i++) {
        const obj = array[i];

        if (predicate(obj)) {
            array[end++] = obj;
        }
    }

    array.length = end;
};

const toDelete = new Set(['abc', 'efg']);

const arrayOfObjects = [{id: 'abc', name: 'oh'},
                        {id: 'efg', name: 'em'},
                        {id: 'hij', name: 'ge'}];

filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);

If you don’t need to do it in place, that’s Array#filter:

const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));

You can remove an item by one of its properties without using any 3rd party libs like this:

var removeIndex = array.map(item => item.id).indexOf("abc");

~removeIndex && array.splice(removeIndex, 1);

With lodash/underscore:

If you want to modify the existing array itself, then we have to use splice. Here is the little better/readable way using findWhere of underscore/lodash:

var items= [{id:'abc',name:'oh'}, // delete me
                  {id:'efg',name:'em'},
                  {id:'hij',name:'ge'}];

items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);

With ES5 or higher

(without lodash/underscore)

With ES5 onwards we have findIndex method on array, so its easier without lodash/underscore

items.splice(items.findIndex(function(i){
    return i.id === "abc";
}), 1);

(ES5 is supported in almost all morden browsers)

About findIndex, and its Browser compatibility


findIndex works for modern browsers:

var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = myArr.findIndex(function(o){
  return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);