klferreira
klferreira

Reputation: 332

Determine whether an array contains a value and update or create it

So i have this Cart object in Javascript... What i want to do is check if an item is present in the given cart.

I've done it this way

let item = {id: this.id, name: this.name, price: this.price, amount: this.amount}
let hasItem = false;

this.cart.items.forEach(element => {
    if (element.id === item.id) {
        element.amount += item.amount
        hasItem = true; 
    }
})
if (!hasItem) {
    this.cart.items.push(item);
}

It works fine, but i was wondering if there is a faster, more effective way of doing this... What would you suggest?

Upvotes: 2

Views: 444

Answers (3)

Rajib Chy
Rajib Chy

Reputation: 880

Try it

let item = { id: this.id, name: this.name, price: this.price, amount: this.amount };

typeof ( this.cart.items.find( a => { return a.id === item.id ? ( a.amount += item.amount, true ) : false; } ) ) !== 'object' ? this.cart.items.push( item ) : undefined;

Upvotes: -1

georg
georg

Reputation: 215019

A more efficient way would be to use a proper data structure (Map) instead of the array, for example:

let basket = new Map();

function add(product) {
    if(basket.has(product.id))
        basket.get(product.id).amount += product.amount;
    else
        basket.set(product.id, {...product});
}

add({id:1, name: 'bread', amount:1});
add({id:2, name: 'butter', amount:2});
add({id:1, name: 'bread', amount:2});
add({id:1, name: 'bread', amount:1});

console.log([...basket.values()])

This way, you have guaranteed O(1) lookup by the product id.

Upvotes: 2

31piy
31piy

Reputation: 23859

Use Array#find method. The biggest advantage is that if the item is found in the array, it doesn't traverse the array further (which forEach does, and you can't stop it from doing so).

let item = {id: this.id, name: this.name, price: this.price, amount: this.amount};
let listItem = this.cart.items.find(element => element.id === item.id)

if (!listItem) {
    this.cart.items.push(item);
} else {
    listItem.amount += item.amount;
}

Upvotes: 2

Related Questions