How to count values in an json object array? (In VueJS) - javascript

i'm trying to sum up a couple of properties in an object.
I'm using a VueJS filter, in combination with the ES5 reduce function to add up the numbers to get a total.
Well, it's not working at this moment. Somebody care to help me out?
new Vue({
el: '.app',
data: {
products: [{
"pid": "37",
"pname": "Reprehenderit",
"price": "4.29",
"amount": "1"
}, {
"pid": "45",
"pname": "Sit",
"price": "1.00",
"amount": "4"
}, {
"pid": "67",
"pname": "Omnis",
"price": "7.00",
"amount": "2"
}],
}
});
Vue.filter('subtotal', function (list, key1, key2) {
return list.reduce(function(total, item) {
return total + item.key1 * item.key2
}, 0)
})
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<div class="app">
Product example: {{ products[0].pname }}
<br><br>
Total: {{ products | subtotal 'price' 'amount' }}
</div>

Looks like your event handler is being initialized after the vue is already constructed. If your events aren't attached when they're called they'll be ignored.
Also, you can't reference your object properties like that product.variable you'll need to use product[variable]
Vue.filter('subtotal', function (list, key1, key2) {
return list.reduce(function(total, item) {
return total + item[key1] * item[key2]
}, 0)
})
new Vue({
el: '.app',
data: {
products: [{
"pid": "37",
"pname": "Reprehenderit",
"price": "4.29",
"amount": "1"
}, {
"pid": "45",
"pname": "Sit",
"price": "1.00",
"amount": "4"
}, {
"pid": "67",
"pname": "Omnis",
"price": "7.00",
"amount": "2"
}],
}
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<div class="app">
Product example: {{ products[0].pname }}
<br><br>
Total: {{ products | subtotal 'price' 'amount' }}
</div>

You could get the value of key like this:
return total + item[key1] * item[key2]
Also, you should set the filter before the vue instance.

Related

How can I .filter an object by elements within an array inside an object?

I've been playing around trying to learn in an API project using Postman and conducting tests using JavaScript. So far, I have succeeded with the help of reading on websites and watching YouTube videos. Of course, previous tests and playing around have been fairly easy but now I came to a stop. I really tried to figure this out for several weeks but I need further guidance, a push in the right direction or direct help.
What I'm trying to do is to filter out some of the response to only view objects that contain specific data.
To do that, I'm using a filter where I want all products containing a specific value inside an array "product_option_values".
My first approach was to see if I could sort products having any values from the first array, and it worked. It filters just fine.
var filterSmall = jsonData.products.filter(fs => fs.associations.product_option_values);
My next approach was to get to my goal of filtering out products according to specific values inside this array. I tried many simple .(dot) combinations and pointing to [index] to access it without any luck. (I must add that I know how to access this from a specific product, but that way doesn't work when filtering).
I've also tried other approaches such as:
var filterSmall = jsonData.products.filter(fs => fs.associations["product_option_values", 0, "name"] === "S");
and other similar combinations.
This is a very shortened sample of the structure of "products" which in its full form consists of 20 products and far more values inside of it:
{
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
}
and here is a small and expanded sample from product_option_values:
{
"product_option_values": [
{
"id": 1,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
}
How do I proceed? Did I do anything correct or even close to it?
Perhaps I've been staring at this for too long.
Thanks in advance.
If you want to compare nested attributes you have to transform the objects (e.g. by using a map operation), so that the relevant attributes are easily accessible for a comparison. If you want to filter by product_option_value id, you could do something like this:
const jsonData = {
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
};
const sample = {
"product_option_values": [
{
"id": 22,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
};
const ids = sample.product_option_values.map((el) => String(el.id));
console.log(ids);
const filtered = jsonData.products.filter((fs) => fs.associations.product_option_values.map((e) => e.id).some((f) => ids.includes(f)));
console.log(filtered);

How to display items always in the same order when mapping over an array?

I've created a cart to which items can be added or removed. At some point in my app I'm displaying this cart, which will have max 3 items. However, the order of the items change as I add/remove from the cart.
{cartItems.map( item => <p key={`${item.type}-${item.id}`}>{item.name || item.time}</p>)}
The items being added have a type property which could be used for setting an order, but I've not been able to use it in my favour.
Two examples of items:
{
"id": "0",
"type": "service",
"name": "Painting",
"isFavorite": false
}
{
"id": "0",
"type": "time",
"day": "today",
"time": "09:40",
"isFavorite": false
}
how can I always display object with 'time' type before 'service'?
const array = [{
"id": "0",
"type": "service",
"name": "Painting",
"isFavorite": false
},
{
"id": "1",
"type": "time",
"day": "today",
"time": "09:40",
"isFavorite": false
}, {
"id": "2",
"type": "time",
"day": "yesterday",
"time": "09:30",
"isFavorite": false
}, {
"id": "3",
"type": "service",
"name": "Some Service",
"isFavorite": false
}
];
const sortedArray = array.reduce((acc, object) => {
const method = 'time' in object ? 'unshift' : 'push';
acc[method](object);
return acc;
}, []);
console.log(sortedArray);
You can write a simple comparison function, which you then use in the array sort.
function compare(a, b) {
if (a.type === b.type) return 0;
else if (a.type === 'time') return -1;
return 1;
}
var cartItems = [{
"id": "0",
"type": "service",
"name": "Painting",
"isFavorite": false
}, {
"id": "0",
"type": "time",
"day": "today",
"time": "09:40",
"isFavorite": false
}]
cartItems.sort(compare);
And then you can simply call your map on sortedItems as before
{cartItems.map( item => <p key={`${item.type}-${item.id}`}>{item.name || item.time}</p>)}

How to get the sum of children values of an object in a Javascript react native?

Here is my object:
var obj = {
"idtransact1": {
"amount": 3000,
},
"idtransact2": {
"amount": 3000,
}
}
I am trying to get the sum of all amount.
I tried to adapt this example but since it is not the same data structure then i am a bit lost.
var array = [{
"adults": 2,
"children": 3
}, {
"adults": 2,
"children": 1
}];
var val = array.reduce(function(previousValue, currentValue) {
return {
adults: previousValue.adults + currentValue.adults,
children: previousValue.children + currentValue.children
}
});
console.log(val);
Any help would be appreciated.
You can use Object.values() and .reduce() to get the sum:
const data = {
"idtransact1": { "amount": 3000 },
"idtransact2": { "amount": 3000 }
};
const result = Object.values(data).reduce((r, { amount }) => r + amount, 0);
console.log(result);
Using forEach loop
var obj = {
"idtransact1": {
"amount": 3000,
},
"idtransact2": {
"amount": 3000,
}
}
var sum=0;
Object.values(obj).forEach((x)=>sum+=x.amount)
console.log(sum)
A for in loop is your friend when it comes to looking for values in an object.
var obj = {
"idtransact1": {"amount": 3000},
"idtransact2": {"amount": 3000}};
var sumAmount = 0;
for(var char in obj){
sumAmount += obj[char].amount;
}
console.log(sumAmount);
For your second example, the for in loop works the same way with the array of objects.
var array = [
{"adults": 2,"children": 3},
{"adults": 2,"children": 1}];
var sumAdults = 0;
var sumChildren = 0;
for(var char in array){
sumAdults += array[char].adults;
sumChildren += array[char].children;
}
console.log(sumAdults + " " + sumChildren);
Less to remember if you can look for data in objects and data in an array of objects the same way. Enjoy
Array [
Object {
"product": Object {
"cat_id": "20",
"cat_name": "Pizza",
"detail": "Pizza sauce, Green pepper & mozarella cheese",
"discount_price": "",
"has_extra": "0",
"has_variation": "1",
"id": "46",
"image": "chicken-tikka-piza-recipe-main-photo.jpg",
"name": "Chicken Fajita",
"prep_time": "30",
"price": "310",
"status": "1",
"time_stamp": "2021-01-02 19:43:41",
"ven_id": "6",
},
"quantity": 1,
},
Object {
"product": Object {
"cat_id": "20",
"cat_name": "Pizza",
"detail": "Pizza Sauce, Tomato Green Paper, Olives Mashrooms And Chipotle Sauce with extra Creamy mayoneese",
"discount_price": "",
"has_extra": "0",
"has_variation": "0",
"id": "45",
"image": "chicken-tikka-piza-recipe-main-photo.jpg",
"name": "Chicken Tikka",
"prep_time": "15",
"price": "310",
"status": "1",
"time_stamp": "2021-01-02 19:41:56",
"ven_id": "6",
},
"quantity": 3,
},
]
How to calculate its total price where quantity is not the same also I want to calculate total price

Create a Json structure from arrays by code - Typescript

I must create a Json object that represent a Sandwich configuration (bread, meat, sauces etc...) from different arrays that contains the ingredients for each category (1 array for bread, 1 for meat etc...) like this {name: 'x', price: 'y'}
The categories are defined but each array can have a different number of elements.
It's possible to obtain, starting from these arrays, something like that by code? I need this to make a recap of my sandwich in the cart page after the user choose all the ingredients. (each cat_1 it's a type of ingredient).
sandwich{
"cat_1": {[
{
"name": "x",
"price": "x"
}
]
},
"cat_2": {[
{
"name": "x",
"price": "x"
}
]
},
"cat_3": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
},
"cat_4": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
},
"cat_5": {[
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
},
{
"name": "x",
"price": "x"
}
]
}
}
I don't post any code beacuse I don't know what can help.
Actually, I push all my arrays into a big array and I have something like that, but it's a lot different from what I want achieve.
[{
"name": "Montanaro",
"price": "5.00"
}, {
"name": "Manzo",
"price": "5.00"
}, {
"name": "Fossa",
"price": "1.00"
}, {
"name": "Caciotta",
"price": "1.00"
}, {
"name": "Guacamole",
"price": "0.50"
}, {
"name": "Olive ascolane",
"price": "1.00"
}, {
"name": "Mozzarelline fritte",
"price": "0.50"
}, {
"name": "Onion Rings",
"price": "1.00"
}]
I'm not a json expert so I don't know where to start...
Thank you to everyone that could help me.
Have a good day
Have you tried to split the ingredients and add an element from the list for each sandwich?
let breads = [{name: "bread1", price: 1.00}, {name: "bread2", price: 2.00}, {name: "bread3", price: 3.00}];
let meats = [{name: "meat1" , price: 1.00}, {name: "meat2" , price: 2.00}, {name: "meat3" , price: 3.00}];
let sauces = [{name: "sauce1", price: 1.00}, {name: "sauce2", price: 2.00}, {name: "sauce3", price: 3.00}];
let s1 = {
bread : breads[Math.floor(Math.random()*breads.length)],
meats : meats[Math.floor(Math.random()*meats.length)],
sauces : sauces[Math.floor(Math.random()*sauces.length)]
}
let sandwich = {s1};
console.log(sandwich);
Here is an example: https://codepen.io/WildLlama/pen/VVLYmL?editors=0011

Convert clustered obj to array

I want to use the library markdown-table to generate out of my object a table. The pre-requirement is to create an array with a certain structure.
Find below my minimum viable example:
const obj = {
"2": {
"title": "Product 1",
"category": [{
"cat_name": "Graphic Card"
}],
"currency": "$",
"price": "513.40"
},
"3": {
"title": "Product 2",
"category": [{
"cat_name": "Graphic Card"
}],
"currency": "$",
"price": "599.00",
},
"4": {
"title": "Memory Ram 1",
"category": [{
"cat_name": "Memory"
}],
"currency": "$",
"price": "25.99",
},
"5": {
"title": "Product 3",
"category": [{
"cat_name": "Graphic Card"
}],
"currency": "$",
"price": "688.88",
},
"6": {
"title": "Adapter 1",
"category": [{
"cat_name": "PCI-E"
}],
"currency": "$",
"price": "48.99",
}
}
var result = Object.keys(obj).map(function(key) {
return [Number(key), obj[key]];
});
console.log(result)
<script src="https://raw.githubusercontent.com/wooorm/markdown-table/master/index.js"></script>
I am getting the following result for my table:
| 2 | [object Object] |
| --- | --------------- |
| 3 | [object Object] |
| 4 | [object Object] |
| 5 | [object Object] |
| 6 | [object Object] |
However, the result array I am trying to get should look like the following:
[
['Category', 'Model', 'Price'],
['Graphic Card', 'Prod 1', '$513.40'],
['Graphic Card', 'Product 2', '$599.00'],
['Graphic Card', 'Product 3', '$688.88'],
['Memory', 'Memory Ram 1', '$25.99'],
['PCI-E', 'Adapter 1', '$48.99']
]
Any suggestions why my array is not parsed correctly and [object Object] is shown?
I appreciate your replies!
[object Object] what you get when you call .toString() on an object.
It looks like you need to explicitly pass markdown-table the values you want displayed, as all it's doing is calling .toString() on what you pass in. I don't see where it will derive the headers and values for you.
Something like this might do the trick:
let result = Object.keys(obj)
.reduce((result, key) => {
result.push([obj[key].category[0].cat_name, obj[key].title, obj[key].currency + obj[key].price]);
return result;
},
[['Category', 'Model', 'Price']]
);
What's going on here is I'm passing in the headers as the initial value of the accumulator in .reduce(), and each iterations is pushing a row of values onto the accumulated array.
If you want to sort the results:
let result = Object.keys(obj)
.sort((a, b) => {
if (obj[a].category[0].cat_name < obj[b].category[0].cat_name)
return -1;
if (obj[a].category[0].cat_name > obj[b].category[0].cat_name)
return 1;
if (obj[a].model < obj[b].model)
return -1;
if (obj[a].model > obj[b].model)
return 1;
return 0;
})
.reduce(...
Here's a fiddle: https://jsfiddle.net/jmbldwn/t8Lvw2bj/2/
You can use Object.values() to get the values from your object and then using array#map with object and array destructuring you can generate the desired array. Then using local#compare and array#sort, sort the array alphabetically. Then you using array#unshift you can add the ['Category', 'Model', 'Price'] at the beginning of array.
const obj = { "2": {"title": "Product 1", "category": [{ "cat_name": "Graphic Card" }], "currency": "$", "price": "513.40" }, "3": { "title": "Product 2", "category": [{ "cat_name": "Graphic Card" }], "currency": "$", "price": "599.00", }, "4": { "title": "Memory Ram 1","category": [{ "cat_name": "Memory" }], "currency": "$", "price": "25.99", }, "5": { "title": "Product 3", "category": [{ "cat_name": "Graphic Card" }], "currency": "$", "price": "688.88", }, "6": { "title": "Adapter 1", "category": [{ "cat_name": "PCI-E"}], "currency": "$", "price": "48.99", } };
let result = Object
.values(obj)
.map(({title, category : [{cat_name}], currency, price}) => [cat_name, title, `${currency}${price}`])
.sort((a,b) => a[0].localeCompare(b[0]) || a[1].localeCompare(b[1]));
result.unshift(['Category', 'Model', 'Price']);
console.log(result);

Categories

Resources