anonym
anonym

Reputation: 4850

Why doesn't the splice method remove all the items from an array with matching property values?

I'm trying to remove items from orders[] array where the tableNumber provided in the function parameter matches table_id.

orders = [
    {food_id: 5, table_id: 1},
    {food_id: 5, table_id: 2},
    {food_id: 5, table_id: 1},
    {food_id: 5, table_id: 1},
    {food_id: 5, table_id: 2},
    {food_id: 5, table_id: 3},
];

removeAllOrdersForTable(tableNumber: Table): void
{
    for (let order of this.orders) {
        let match = (order.table_id == tableNumber);
        match ? this.orders.splice(this.orders.indexOf(order), 1) : null;
    }
}

If I execute removeAllOrdersForTable(1), it still leaves some items in orders[] array with table_id of 1. When I console.log(orders) after the function execution, I still get something like the following:

Array[1]
0: Object {food_id: 5, table_id: 1},
1: Object {food_id: 3, table_id: 1},

Is this the appropriate way to remove multiple objects from an array that match an object property values?

Upvotes: 0

Views: 72

Answers (3)

trincot
trincot

Reputation: 350365

As you remove items while you have a loop on the same array, there will be items that get skipped in the loop.

Why not use filter? It does what you need, and you can assign the result back to this.items:

removeAllOrdersForTable(tableNumber: Table): void
{
    this.orders = this.orders.filter(order => order.table_id == tableNumber);
}

The filter method creates a new array with the matches. By assigning that result back to this.orders you replace the original array, by the array of matches.

Mutating the array

In case you need this.orders array to keep its original reference, then you can use splice just once, namely by removing all original elements and inserting the filter matches instead. But only do this if the previous method does not work because of other dependencies in your code:

removeAllOrdersForTable(tableNumber: Table): void
{
    this.orders.splice(0, this.orders.length, 
                          ...this.orders.filter(order => order.table_id == tableNumber);
}

Upvotes: 3

Vladu Ionut
Vladu Ionut

Reputation: 8193

   var newArray = this.orders.slice();
    for (let order of newArray) {
        let match = (order.table_id == tableNumber);
        match ? this.orders.splice(this.orders.indexOf(order), 1) : null;
    }

Upvotes: 1

Ali Baig
Ali Baig

Reputation: 3867

Try using this

var _orders = this.orders.slice();
for (let order of _orders) {
    if(order.table_id == tableNumber){
        var index = this.orders.indexOf(order);
        this.orders.splice(index, 1);
    }
}

Upvotes: 1

Related Questions