How to sum multiple different objects in an array using Vuejs? - javascript

I am getting started with Vue. I am struggling to calculate the sum of different elements in an object of an array.
My array looks like this:
sites: [{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}]
},
{
sku: 10002,
name: "Product B",
totalPrice: '',
values: [{
price: 13,
discount: 3,
color: "purple"
},
{
price: 20,
discount: 5,
color: "green"
}]
}]
I am trying to sum the price and set it to totalPrice. So the array will change totalPrice as below:
sku: 10001,
name: "Product A",
totalPrice: 25,
sku: 10002,
name: "Product B",
totalPrice: 33,
I believe I need to use something like the below to sum them, however I cannot figure out how to do this!
computed: {
total(){ return this.sites.reduce( (total, item) => item.values. price + total ,0);}
},
How do I calculate the sum of the price and set it as the totalPrice?
I have traveled SO and find similar threads however nothing that I can get to work with my issue.

computed: {
total() {
let newojv = []
sites.forEach((item, _) => {
let s = item.values.map((items2, _) => {
return items2.price;
})
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
});
return newojv;
}
}
First for Each of the array of objects below
{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
}
And then for Each of the array of objects below
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
We take a we map the array to get the values of the price, which is 10,15. Then we reduce the array, add it and then push it.
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
A working example can be
let sites = [{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
}, {
sku: 10002,
name: "Product B",
totalPrice: '',
values: [{
price: 13,
discount: 3,
color: "purple"
},
{
price: 20,
discount: 5,
color: "green"
}
]
}]
let newojv = []
sites.forEach((item, _) => {
let s = item.values.map((items2, _) => {
return items2.price;
})
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
});
console.log(newojv)

Related

Comparing and editing an array

There are two arrays:
const products = [
{
id: 123,
stock: [
{
colors: [{ color: "red", stock: 12 }],
size: "S",
},
],
},
{
id: 321,
stock: [
{
colors: [{ color: "blue", stock: 10 }],
size: "L",
},
],
},
];
and
const incart = [
{
id: 123,
color: "red",
qty: 1,
size: "S",
},
{
id: 321,
color: "blue",
size: "L",
qty: 2,
},
];
When a user purchases the items they have in their cart. I'd like to update the products array stock object if the color and size match.
I'm thinking about a filter and reduce but not sure how to implement it.
You can easily achieve this using forEach and find
const products = [
{
id: 123,
stock: [
{
colors: [{ color: "red", stock: 12 }],
size: "S",
},
],
},
{
id: 321,
stock: [
{
colors: [{ color: "blue", stock: 10 }],
size: "L",
},
],
},
];
const incart = [
{
id: 123,
color: "red",
qty: 1,
size: "S",
},
{
id: 321,
color: "blue",
size: "L",
qty: 2,
},
];
incart.forEach((curr) => {
const { id, color, qty, size } = curr;
const isExist = products.find((obj) => obj.id === id);
if (isExist) {
const stockObj = isExist.stock.find((s) => s.size === size);
if (stockObj) {
const colorObj = stockObj.colors.find((c) => c.color === color);
if (colorObj) colorObj.stock -= qty;
}
}
});
console.log(products);

How to get the aggregation of an array in javascript

I am trying to aggregate my list of orders im getting in my database into an array of orders with different prices.
Example of array from my db:
[{
id: 1,
price: 10,
item: 'apple'
}, {
id: 2,
price: 10,
item: 'apple',
}, {
id: 3,
price: 20,
item: 'apple'
}]
i want to aggregate the orders based on the price ... if the price is the same make them into one array
what i want to return:
[{
price: 10,
item: 'apple',
quantity: 2
}, {
price: 20,
item: apple,
quantity: 1
}]
so as seen above if the price is the same aggregate them to one object and increase the quantity and return that to my users.
const data = [{
id: 1,
price: 10,
item: 'apple'
}, {
id: 2,
price: 10,
item: 'apple',
}, {
id: 3,
price: 20,
item: 'apple'
}];
let x = data.reduce((items, item) => {
let found = false;
delete(item.id)
items.forEach(el => {
if (el.price == item.price && el.item == item.item) {
found = true;
el.quantity++;
}
})
if (!found) {
item.quantity = 1;
items.push(item)
}
return items
}, [])
console.log(x)

How would I prevent duplicates in array of objects? And if there is a object with same property, it should sume its value

So basically what I am trying to achieve is.. I have an array with objects, in my case array of items in stock. And when I add item to cart array, it should check if an object with the same property (name) already exists. And if it exists, it should just sum the count of them. So that I don't have duplicates... But it sums the count.
const stock = [
{
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 0,
logoURL: process.env.PUBLIC_URL + '/images/1.png',
},
{
id: 1,
name: 'Generator',
price: 1299,
stock: 12,
count: 0,
logoURL: process.env.PUBLIC_URL + '/images/2.png',
},
{
id: 2,
name: 'Log Splitter',
price: 2133,
stock: 5,
count: 0,
logoURL: process.env.PUBLIC_URL + '/images/3.png',
},
{
id: 3,
name: 'Lawn Mower',
price: 250,
stock: 24,
count: 0,
logoURL: process.env.PUBLIC_URL + '/images/4.png',
},
{
id: 4,
name: 'Chainsaw',
price: 344,
stock: 16,
count: 0,
logoURL: process.env.PUBLIC_URL + '/images/5.png',
},
];
This:
const shoppingCart = [
{
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 5,
logoURL: process.env.PUBLIC_URL + '/images/1.png',
},
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 3,
logoURL: process.env.PUBLIC_URL + '/images/1.png',
}
]
Should be:
const shoppingCart = [
{
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 8,
logoURL: process.env.PUBLIC_URL + '/images/1.png',
}
]
You can check if the objectToBeAdded is already there in the shoppingCart. And then update shoppingCart accordingly.
const indexOfObject = shoppingCart.findIndex(item => item.name === objectToBeAdded.name);
if(indexOfObject > -1) {
shoppingCart[indexOfObject].count += objectToBeAdded.count;
} else {
shoppingCart = [...shoppingCart, objectToBeAdded];
}
You can do this by using array reduce method. Just traverse the array and sum the count property.
const shoppingCart = [
{
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 5,
logoURL: `process.env.PUBLIC_URL + '/images/1.png`,
},
{
id: 0,
name: 'Leaf Blower',
price: 250,
stock: 24,
count: 3,
logoURL: `process.env.PUBLIC_URL + '/images/1.png`,
},
];
let ret = shoppingCart.reduce((prev, c) => {
const p = prev;
if (!p[c.id]) p[c.id] = { ...c };
else p[c.id] = { ...c, count: c.count + p[c.id].count };
return p;
}, {});
ret = Object.values(ret);
console.log(ret);
Something like this should work:
if (!shoppingCart.find(element => element.name == objectToBeAdded.name)) {shoppingCart.push(objectToBeAdded)}
Here, you use Array.find() to check if there is an object with a matching name in the array. If not, you add the object to array.

ES6: Populate object value with a value from another object when ID is present

I would like to populate the value 'discount' for a product with the discount ID value from the array discounts, if the respective product ID exists as a value in the Discounts object.
const products = [{
id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d",
name: "SANTO - Schnürstiefelette",
price: 199.95,
discount: 0,
},
{
id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5",
name: "AIR FORCE 1 07 LV8 - Sneaker low",
price: 109.95,
discount: 0,
},
{
id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e",
name: "DUFF 9.0 - Sporttasche",
price: 34.95,
discount: 0,
},
{
id: "471ad894-150b-4a2b-881c-a9a4dbc4b401",
name: "Strickpullover",
price: 20.99,
discount: 0,
},
];
const discounts = [{
id: "5791ae04-a704-4f44-808b-de5ddb8812b5",
name: "Christmas discount",
productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"],
active: true
},
{
id: "5791ae04-a704-4f44-808b-de5ddb8812e6",
name: "Christmas discount 2",
productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"],
active: true
}
];
At the end i need it like:
const products = [{
id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d",
name: "SANTO - Schnürstiefelette",
price: 199.95,
discount: '5791ae04-a704-4f44-808b-de5ddb8812e6',
},
...
...
You could use map() to transform products array. And find() and includes() to check if discount exists for a product.
const products = [{ id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d", name: "SANTO - Schnürstiefelette", price: 199.95, discount: 0, }, { id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5", name: "AIR FORCE 1 07 LV8 - Sneaker low", price: 109.95, discount: 0, }, { id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e", name: "DUFF 9.0 - Sporttasche", price: 34.95, discount: 0, }, { id: "471ad894-150b-4a2b-881c-a9a4dbc4b401", name: "Strickpullover", price: 20.99, discount: 0, }, ];
const discounts = [{ id: "5791ae04-a704-4f44-808b-de5ddb8812b5", name: "Christmas discount", productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"], active: true }, { id: "5791ae04-a704-4f44-808b-de5ddb8812e6", name: "Christmas discount 2", productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"], active: true } ];
let result = products.map(product => {
let discount = discounts.find(item => item.productIds.includes(product.id));
return {
...product,
"discount": discount ? discount.id : product.discount
};
});
console.log(result);
You could store the discounts in a Map and map the object with a new discount object, if necessary.
var products = [{ id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d", name: "SANTO - Schnürstiefelette", price: 199.95, discount: 0 }, { id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5", name: "AIR FORCE 1 07 LV8 - Sneaker low", price: 109.95, discount: 0 }, { id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e", name: "DUFF 9.0 - Sporttasche", price: 34.95, discount: 0 }, { id: "471ad894-150b-4a2b-881c-a9a4dbc4b401", name: "Strickpullover", price: 20.99, discount: 0 }],
discounts = [{ id: "5791ae04-a704-4f44-808b-de5ddb8812b5", name: "Christmas discount", productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"], active: true }, { id: "5791ae04-a704-4f44-808b-de5ddb8812e6", name: "Christmas discount 2", productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"], active: true }],
ids = discounts.reduce((m, { id, productIds }) => productIds.reduce((n, pid) => n.set(pid, id), m), new Map);
products = products.map(p => Object.assign({}, p, ids.has(p.id) && { discount: ids.get(p.id) }));
console.log(products);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nested loop through both products and discounts array, if the product id is included inside the productIds array of any of the objects in the discounts array, assign the discount id to the product discount.
for (let product of products) {
for (let discount of discounts) {
if (discount.productIds.includes(product.id)){
product.discount = discount.id;
break;
}
}
}

Merge Object preserving it's value using addition in javascript

I have the js object array structured as given below,
items= [
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
},
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
},
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
}
]
I want to avoid duplication of objects based on name property. So I decided to merge them by preserving its evaluation as illustrated below,
Use Case
consider property name, here in above array Floy Vandervort repeats 3 times. To convert it into a single object, merge them into a single object by preserving the value by addition. So, the properties discount, quantity and taxable should be merged by addition except for price property.
I'm looking for an optimal solution, I achieved using iterating over the original array and pushing merged object to another array. I want to eliminate the complexity, is it possible? if yes, how? Here is the function I'm using
function(items) {
let filtered = [];
items.forEach((item) => {
if (!isContains(filtered, item)) {
filtered.push(item);
} else {
index = filtered.findIndex((x) => x.name === item.name);
filtered[index].discount += item.discount;
filtered[index].quantity += item.quantity;
filtered[index].taxable += item.taxable;
}
});
return filtered;
}
function isContains(items, ob) {
items.forEach((item) => {
if (item.name === ob.name) {
return true;
}
});
return false;
}
Returning inside a forEach callback has no effect - isContains will always return false. Better to use an object or Map indexed by the name instead, to reduce computational complexity by an order of magnitude - then you can get that object's values to get the array you want:
const items=[{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34},{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34},{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34}];
function squish(items) {
const squishedItemsByName = items.reduce((a, { name, ...props }) => {
if (!a[name]) {
a[name] = { name };
}
Object.entries(props).forEach(([prop, val]) => {
a[name][prop] = (a[name][prop] || 0) + val;
});
return a;
}, {});
return Object.values(squishedItemsByName);
}
console.log(squish(items));
Try
let h = {};
items.forEach(x=> h[x.name]= !h[x.name] ? x : {
discount: h[x.name].discount+x.discount,
name: x.name,
price: x.price,
quantity: h[x.name].quantity+x.quantity,
taxable: h[x.name].taxable+x.taxable
});
let result = Object.keys(h).map(k=> h[k]);
items= [
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
},
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
},
{
discount: 27.6,
name: 'Floy Vandervort',
price: 230,
quantity: 3,
taxable: 662.4
},
{
discount: 122.88,
name: 'Adriel Abshire II',
price: 256,
quantity: 6,
taxable: 1413.12
},
{
discount: 159.66,
name: 'Tabitha Stroman',
price: 887,
quantity: 2,
taxable: 1614.34
}
]
let h = {};
items.forEach(x=> h[x.name]= !h[x.name] ? x : {
discount: h[x.name].discount+x.discount,
name: x.name,
price: x.price,
quantity: h[x.name].quantity+x.quantity,
taxable: h[x.name].taxable+x.taxable
});
let result = Object.keys(h).map(k=> h[k]);
console.log(result);
One of many ways of doing this could be the following :
const uniqueItems = Object.values(
items.reduce((hashMap, item) => {
if (!hashMap[item.name]) {
hashMap[item.name] = { ...item };
} else {
// You should use a safest way to add
hashMap[item.name].discount += item.discount;
hashMap[item.name].price += item.price;
hashMap[item.name].quantity += item.quantity;
hashMap[item.name].taxable += item.taxable;
}
return hashMap;
}, {})
)

Categories