I am playing with JS objects. And I came across a challenging situation for me:
basically I have a JS object:
let cinfo = {
"costing_T063623477Z":{
"service":[
{
"objid":"T063637283Z",
"serviceid":"SRV2100003",
"servicename":"FABRICATION OF SPRINKLER & HOSE",
"estimatedprice":"10000.00",
"description":"sdfg",
"laborcost":"500.00"
}
],
"othercharges":[
{
"objid":"T063911531Z",
"description":"Other Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063906963Z",
"description":"Sales Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"345.00",
"remarks":"345"
}
]
}
}
I have something that can get the values of a specific object:
Object.keys(cinfo).forEach(function(ckey) {
cinfo[ckey].service.forEach(function(skey){
console.log(skey.laborcost);
})
})
Based on the object above, the console output is: 500.00
But, I want something conditional when it comes to othercharges
object.
I need to get the amount based only on the description:
Something like this:
Object.keys(cinfo).forEach(function(ckey) {
cinfo[ckey].othercharges.forEach(function(skey){
console.log(skey.amount) //-> where "description" = "Other Expenses";
console.log(skey.amount) //-> where "description" = "Sales Expenses";
console.log(skey.amount) //-> where "description" = "Delivery Expenses";
})
}
How to make it possible? Thanks.
CodePudding user response:
Something like this?
let cinfo = {
"costing_T063623477Z":{
"service":[
{
"objid":"T063637283Z",
"serviceid":"SRV2100003",
"servicename":"FABRICATION OF SPRINKLER & HOSE",
"estimatedprice":"10000.00",
"description":"sdfg",
"laborcost":"500.00"
}
],
"othercharges":[
{
"objid":"T063911531Z",
"description":"Other Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063906963Z",
"description":"Sales Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"100.00",
"remarks":"345"
}
]
}
}
const getServiceCharge = (info) => {
const key = Object.keys(info)[0]; // Get first key in object
return info[key].service[0].laborcost;
}
const getOtherCharge = (info, desc) => {
const key = Object.keys(info)[0]; // Get first key in object
const otherCharges = info[key].othercharges;
const sumAmount = otherCharges
.filter(item => item.description === desc) // Get only items we are looking for
.reduce((sum, item) => sum Number(item.amount), 0); // Sum amount
return sumAmount;
}
console.log(`Service Labor charge: ${getServiceCharge(cinfo)}`);
console.log(`Service Other Expenses charge: ${getOtherCharge(cinfo, "Other Expenses")}`);
console.log(`Service Sales Expenses charge: ${getOtherCharge(cinfo, "Sales Expenses")}`);
console.log(`Service Delivery Expenses charge: ${getOtherCharge(cinfo, "Delivery Expenses")}`);
CodePudding user response:
Object.keys(cinfo).forEach(function(ckey) {
// Get only 1 other charges
// Return object
const deliveryExpenses = cinfo[key].othercharges.find(item => item.description == "Delivery Expenses")
// Get all other charges base on the comparison
// Returns array
const deliveryExpenses = cinfo[key].othercharges.filter(item => item.description == "Delivery Expenses")
}
Heres the docs in using find. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
CodePudding user response:
let cinfo = {
costing_T063623477Z: {
service: [
{
objid: "T063637283Z",
serviceid: "SRV2100003",
servicename: "FABRICATION OF SPRINKLER & HOSE",
estimatedprice: "10000.00",
description: "sdfg",
laborcost: "500.00"
}
],
othercharges: [
{
objid: "T063911531Z",
description: "Other Expenses",
amount: "345.00",
remarks: "345"
},
{
objid: "T063906963Z",
description: "Sales Expenses",
amount: "345.00",
remarks: "345"
},
{
objid: "T063730836Z",
description: "Delivery Expenses",
amount: "345.00",
remarks: "345"
}
]
}
};
function getCharge(serviceCharge = null, otherCharges = null) {
if (serviceCharge) {
return cinfo.costing_T063623477Z.service[0].laborcost;
}
return cinfo.costing_T063623477Z.othercharges.filter(
(t) => t.description === otherCharges
).map(t=>t.amount);
}
console.log(getCharge(true));
console.log(getCharge(null, "Other Expenses"));
console.log(getCharge(null, "Sales Expenses"));
console.log(getCharge(null, "Delivery Expenses"));
Lets do it in a more smart way. I hope It will work.
CodePudding user response:
Here is an answer, using only one loop (through .reduce
), and setting every thing up just by assigning some variables in the right places.
It works with multiple services
or if multiple descriptions
share the same value.
let cinfo = {
"costing_T063623477Z":{
"service":[
{
"objid":"T063637283Z",
"serviceid":"SRV2100003",
"servicename":"FABRICATION OF SPRINKLER & HOSE",
"estimatedprice":"10000.00",
"description":"sdfg",
"laborcost":"500.00"
}
],
"othercharges":[
{
"objid":"T063911531Z",
"description":"Other Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063906963Z",
"description":"Sales Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"345.00",
"remarks":"345"
},
{
"objid":"T063730836Z",
"description":"Delivery Expenses",
"amount":"100.00",
"remarks":"345"
}
]
}
}
function getCost(obj, othercharges) {
let key = Object.keys(obj)[0],
subKey = (othercharges) ? 'othercharges' : 'service',
property = (othercharges) ? 'amount' : 'laborcost',
childObj = obj[key][subKey];
return childObj.reduce((totalSum, item) => {
let itemSum = 0;
if (!othercharges || item.description == othercharges) {
itemSum = item[property];
}
return totalSum Number(itemSum);
}, 0);
}
console.log( getCost(cinfo) ); // returns 'laborcost'
console.log( getCost(cinfo, 'Delivery Expenses') );