Reputation: 5579
I have an indexed list of products, and each product has a price, as well as an array of bulk prices. I want to filter out all bulk prices that are higher than the product's base price. What's the best way to do this with ES6 features like destructuring.
Here is the list of prices:
prices: {
foo: {
price: 160,
bulkPricing: [
{price: 150, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
},
bar: {
price: 160,
bulkPricing: [
{price: 180, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
}
}
You can see that the first bulk price for the second product is higher than the base price so it should be removed. So the result should be:
prices: {
foo: {
price: 160,
bulkPricing: [
{price: 150, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
},
bar: {
price: 160,
bulkPricing: [
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
}
}
I can do it like this:
Object.entries(prices).map(([sku, product])=> {
return {
[sku]: {
...product,
bulkPricing: product.bulkPricing.filter(bp => bp.price < product.price)
}
}
}
)
But this of course returns an array:
[ { foo: { price: 160, bulkPricing: [{price: 150, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}] } },
{ bar: { price: 160, bulkPricing: [{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}] } } ]
So I guess my question is, with the latest ES6 techniques how can I filter items in an object based on arrays within those items, and return that modified object?
Upvotes: 2
Views: 55
Reputation: 20882
ES6 & Destructuring:
Object.keys(prices).reduce((obj, key) => ({
...obj,
[key]: {
...prices[key],
bulkPricing: prices[key].bulkPricing
.filter(({ price }) => price <= prices[key].price)
}
}), {});
Note: it does not use Object.values
as it's not yet widely supported in older browsers and it does not mutate the prices object.
Upvotes: 1
Reputation: 33726
Just use a forEach
along with the function filter
to get only those objects with the price
equal to or lesser than the specific price
.
let obj = { prices: { foo: { price: 160, bulkPricing: [{ price: 150, minimumQuantity: 10 }, { price: 140, minimumQuantity: 20 }, { price: 130, minimumQuantity: 30 } ] }, bar: { price: 160, bulkPricing: [{ price: 180, minimumQuantity: 10 }, { price: 140, minimumQuantity: 20 }, { price: 130, minimumQuantity: 30 } ] } }};
Object.values(obj.prices).forEach(p => p.bulkPricing = p.bulkPricing.filter(b => b.price <= p.price));
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 370979
All you need to do is filter
the bulkPricing
array, creating a copy first to avoid mutation of the original object:
const prices = {
001: {
price: 160,
bulkPricing: [
{price: 150, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
},
002: {
price: 160,
bulkPricing: [
{price: 180, minimumQuantity: 10},
{price: 140, minimumQuantity: 20},
{price: 130, minimumQuantity: 30}
]
}
};
const newPrices = JSON.parse(JSON.stringify(prices));
Object.values(newPrices).forEach((item) => {
const { price: basePrice, bulkPricing } = item;
item.bulkPricing = item.bulkPricing.filter(({ price }) => price < basePrice);
});
console.log(newPrices);
Upvotes: 0