Get the object value based on input objects in javascript - javascript

I would like to how to get the value based on input objects in javascript.
If the source matches the currency and also matches the type in paymentin and paymentout in object then get the value of speed and fees
for example 'SGD' with type_in 'credit' and type_out 'bank' should return the speed and fee
Expected Output:
id: transfer credit: 1 days 1% pay_in: pay_out: bank
id: insta debit: 1 days 1.5% pay_in: pay_out: bank
I tried but i got stuck
function getValue(source,typein,typeout,obj){
var filterArr = source.filter(function(value){
return value.country_from.filter(function(payin){
const in= payin.paymentIn.filter(function(ty){
return ty.type == typein
})
const out = payin.paymentIn.filter(function(ty){
return ty.type == typeout
})
})
})
}
var result = getValue(source,type_in,type_out,obj);
//input objects
var source="SGD";
var type_in="credit";
var type_out="bank";
var obj = [{
"id": "transfer",
"country_from": [{
"currency": [
"SGD",
"USD"
],
"paymentIn": [{
"type": "credit",
"speed": {
"unit": "days",
"number": "1"
},
"fee": {
"type": "%",
"number": "1"
}
}],
"paymentOut": [{
"type": "bank",
"speed": {
"unit": "days",
"number": "2"
}
}]
}]
}, {
"id": "insta",
"country_from": [{
"currency": [
"SGD",
"USD"
],
"paymentIn": [{
"type": "credit",
"speed": {
"unit": "days",
"number": "1"
},
"fee": {
"type": "%",
"number": "1.5"
}
}],
"paymentOut": [{
"type": "bank",
"speed": {
"unit": "days",
"number": "2"
}
}]
}]
}]

I think you have made some mistakes on your initial code, but I guess it is due to the confusion of dealing with so many layers of objects and arrays. This is what you should do:
const getValue = (source, typein, typeout, obj) => {
const res = obj.map(item => {
if (item['country_from'][0]['paymentIn'][0]['type'] === typein
&& item['country_from'][0]['currency'].includes(source)
&& item['country_from'][0]['paymentOut'][0]['type'] === typeout) {
return `id: ${item['id']} credit: ${item['country_from'][0]['paymentIn'][0]['speed']['number']} days credit: ${item['country_from'][0]['paymentIn'][0]['fee']['number']}${item['country_from'][0]['paymentIn'][0]['fee']['type']} pay_in: pay_out: ${item['country_from'][0]['paymentOut'][0]['speed']['number']}`
}
});
return res;
}
getValue('SGD', 'credit', 'bank', obj);
Basically, I will iterate through every element of the input array, obj (which is the one you posted on your question), and within each iteration, I check for the following 3 conditions using the if statement.
1) The paymentIn type matches typein
2) The paymentOut type matches typein
3) currency contains source
Elements that fulfil the above 3 conditions will the string result.
EDIT: To answer your question on the comments, if the paymentIn array has more than one object, we can use Array.some() to check if the object with the type property has the same value as typeIn.
if (item['country_from'][0]['paymentIn'].some(payment => payment['type']===typein)
&& item['country_from'][0]['currency'].includes(source)
&& item['country_from'][0]['paymentOut'][0]['type'] === typeout) {
// to get the object with that typein
const filteredPaymentIn = item['country_from'][0]['paymentIn'].filter(payment => payment['type']===typein)[0];
}

Related

how to store the value of a key for a object and pass it to the function which is a value of another key in the same object

"sideCardInfo": {
"title": "Hospital Admission",
"reportTitle": "Hospital Admission Report",
"subTitle": "Per 1000 Members",
"dateFilter": [
{
"date": previousYearRange,
"value": calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt_py))),
},
{
"date": currentYearRange,
"value": calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt))),
}
],
"percentage": calculatePercentage( calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt_py))), calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt)))),
"tooltipText": ""
},
In the above object inside dateFilter for value i am using a calculateAverage function to get the value i need to pass the same value as parameter for calculatePercentage which is a value for percentage key in the same object how to store the calculateAverage at dateFilter and pass it to calculatePercentage so that i can avoid calculating average two times
To access the properties from within the object you can use getters.
const dataset = {
sideCardInfo: {
title: "Hospital Admission",
reportTitle: "Hospital Admission Report",
subTitle: "Per 1000 Members",
dateFilter: [
{
date: 1,
value: 1
},
{
date: 2,
value: 2
}
],
get percentage(){
return this.dateFilter[0].value + this.dateFilter[1].value;
},
tooltipText: ""
}
};
console.log(dataset.sideCardInfo.percentage);
Simple, use variables to store those results.
E.g
const prevYearAvg = calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt_py)))
const currYearAvg = calculateAverage(allInsightData.map(obj => Number(obj.hospital_admissions_cnt)))
"sideCardInfo": {
"title": "Hospital Admission",
"reportTitle": "Hospital Admission Report",
"subTitle": "Per 1000 Members",
"dateFilter": [
{
"date": previousYearRange,
"value": prevYearAvg,
},
{
"date": currentYearRange,
"value": prevYearAvg,
}
],
"percentage": calculatePercentage(prevYearAvg, prevYearAvg),
"tooltipText": ""
}

remove keys with empty values from json using JS

{
"top": [{
"language": "English",
"value": ""
}, {
"language": "German",
"value": "hASTA"
}],
"bottom": [{
"language": "English",
"value": "jfgfjg"
}, {
"language": "German",
"value": "fkjhf"
}],
"In": "12 am",
"Out": "3 am",
"Type": ""
}
Hi guys, I want to remove the keys that have empty values, I tried using filter but that showed me error in google sheets.
I want to send only the data to API that has values.
In this case, for
language:german, the value is empty so i Would skip sending top. to the API.
the json to be sent:
{
"bottom": [{
"language": "English",
"value": "jfgfjg"
}, {
"language": "German",
"value": "fkjhf"
}],
"In": "12 am",
"Out": "3 am"
}
code used:
apidata = userdata.filter(function(x) { return x !== "" });
Can you please guide me on how to do this?
userdata.filter won't filter the keys of the object.
You can use Array.reduce to create your new object
const json = {
"top": [{
"language": "English",
"value": ""
}, {
"language": "German",
"value": "hASTA"
}],
"bottom": [{
"language": "English",
"value": "jfgfjg"
}, {
"language": "German",
"value": "fkjhf"
}],
"In": "12 am",
"Out": "3 am",
"Type": ""
};
// returns true if it contains a falsy value
// this function is recursive
function checkFalsy(ptr) {
// If we are dealing with an array
if (ptr instanceof Array) {
return ptr.some(x => checkFalsy(x));
}
// If we have a string
if (typeof ptr === 'string') {
return ptr.length === 0;
}
// If we have an object
if (Object.keys(ptr).length) {
return Object.keys(ptr).some(y => checkFalsy(ptr[y]));
}
// anything else
return !!ptr;
}
const filteredJson = Object.keys(json).reduce((tmp, x) => {
// If we are dealing with an array
if (checkFalsy(json[x]) === false) {
tmp[x] = json[x];
}
return tmp;
}, {});
console.log(filteredJson);

Sum column in array if is exactly equal to a existing in javascript

Well guys, I stay mounting one cart of products and I save this items selected on sessionStorage, my JSON saved is this:
[
{
"product": {
"ref": "42101",
"price": 390,
"image": "https://via.placeholder.com/200x200"
},
"combinations": [
{
"type": "REVAS",
"option": "REVVNL"
},
{
"type": "CORAS",
"option": "VNL132"
},
{
"type": "APCAB",
"option": "VNL132"
}
],
"amount": 1
},
{
"product": {
"ref": "42101",
"price": 390,
"image": "https://via.placeholder.com/200x200"
},
"combinations": [
{
"type": "REVAS",
"option": "REVVNL"
},
{
"type": "CORAS",
"option": "VNL132"
},
{
"type": "APCAB",
"option": "VNL132"
}
],
"amount": 5
}
]
All, parameters and order is equal, only the amount is variable, is possible verify if the object is equal and sum the key amount?
I solved it in parts, I'm already grouping and making the sum. But I need to check and iterate the combinations and if the combinations are different, I create a new object, is it possible?
let budgetMap = [{
product: '',
combinations: '',
amount: 0,
}];
let reserseMap = [];
for (var [key, value] of Object.entries(budget)) {
if (typeof reserseMap[value.product.ref] !== 'undefined') {
key = reserseMap[value.product.ref];
} else {
reserseMap[value.product.ref] = key;
}
budgetMap[key].product = value.product;
budgetMap[key].combinations = value.combinations;
budgetMap[key].amount += value.amount;
}

Pull data from JSON object which may not exist

Summary
I receive a large JSON object in node--about 10000 lines--from an external API and I'm creating a new, consolidated javascript object with the data I want.
I'm extracting specific key:value pairs from an object, where another key:value pair in the object matches what I'm looking for. The main issue I'm having is that if there is no data for a specific object, that object is not included and the function I wrote to assign the specific data I want to a variable becomes undefined and crashed my node server.
**Example API Response (Abbreviated) **
I commented on the data I'm trying to extract
{
"ApiJSONObject": {
"id": "t4365qewsagsdga4",
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 6435, //Extract this value and save to specific key in new javascript object
"displayValue": "6,435"
}
],
"segments": [{
"metadata": [{
"key": "segment",
"name": "Segment",
"value": "br.close_solo.season",
"displayValue": null
},
{
"key": "lastPlayedAt",
"name": "Last Played At",
"value": "2018-12-11T16:46:35Z",
"displayValue": "12/11/18 4:46:35 PM"
},
{
"key": "updatedAt",
"name": "Updated At",
"value": "2019-06-10T19:07:00.9143166Z",
"displayValue": "6/10/19 7:07:00 PM"
}
],
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 1, //extract this value and save to specific key in new javascript object based on metaData[0].value
"displayValue": "1"
},
{
"metadata": {
"key": "matchesPlayed",
"name": "Matches Played",
"isReversed": false
},
"value": 1,
"displayValue": "1"
}
]
}]
}
}
Current Function
I wrote this function, however it breaks my code as stats is undefined if there is no data for that specific statsSegment
function getSegmentStats(statType, playerStats) {
let filteredMetaData = [];
for (var i = 0; i < playerStats.segments.length; i++) {
filteredMetaData = playerStats.segments[i].metadata.filter(
val => val["value"] === statType
);
if (filteredMetaData.length) {
return playerStats.segments[i];
}
}
}
function getStatsFields(value,"br.close_solo.season") {
const stat = statsSegment.stats.find(x => x.metadata.name === value);
return stat.value;
}
const seasonSolo = getSegmentStats("br.close_solo.season", playerStats);
const statsObject = { seasonStats: seasonSolo: getStatsFields("Kills", seasonSolo))
The simplest solution would be to just check if your statsSegment is undefined at the start of your function, but first you need to decide what you do in case it is undefined.
you have few options:
throw an error
return an "errored" value- 0, false, -1- something that will never get returned as stat.value and you'll know for sure it means an error.
emit an event of some sort (don't know the context you're using this).
To perform the check simply add if(statSegment === undefined) at the start of getStatField function.
Also, i'd suggest you look at the docs for that 3rd party API you're using and see what undefined return value even means.
And one last thing- this API might return an empty object (also, check at the docs), so the undefined test will pass but you still won't be able to process the data. You can add an empty object test as well:
if(statSegment === undefined || (Object.entries(statSegment).length === 0 && statSegment.constructor === Object));
if you're using ECMA 7+, or:
if(statSegment === undefined || (Object.keys(statSegment).length === 0 && statSegment.constructor === Object));
if you're using ECMPA 5+.
(for more info about this empty object check go here)
When .find() can't find anything which matches its inner function's criteria, it will by default return undefined. By using the logical OR operator (||) you can set the value of stat to be a default object which always has a value of 0:
function getStatsFields(value,"br.close_solo.season") {
const stat = statsSegment && statsSegment.stats.find(x => x.metadata.name === value) || {value: 0};
return stat.value;
}
let statsSegmentJson = {
"ApiJSONObject": {
"id": "t4365qewsagsdga4",
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 6435, //Extract this value and save to specific key in new javascript object
"displayValue": "6,435"
}
],
"segments": [{
"metadata": [{
"key": "segment",
"name": "Segment",
"value": "br.close_solo.season",
"displayValue": null
},
{
"key": "lastPlayedAt",
"name": "Last Played At",
"value": "2018-12-11T16:46:35Z",
"displayValue": "12/11/18 4:46:35 PM"
},
{
"key": "updatedAt",
"name": "Updated At",
"value": "2019-06-10T19:07:00.9143166Z",
"displayValue": "6/10/19 7:07:00 PM"
}
],
"stats": [{
"metadata": {
"key": "kills",
"name": "Kills",
"isReversed": false
},
"value": 1, //extract this value and save to specific key in new javascript object based on metaData[0].value
"displayValue": "1"
},
{
"metadata": {
"key": "matchesPlayed",
"name": "Matches Played",
"isReversed": false
},
"value": 1,
"displayValue": "1"
}
]
}]
}
};
let value = 'Kills';
function getStatsFields(value, statsSegment) {
let statsSegmentStr = JSON.stringify(statsSegment);
let statsSegmentObj = JSON.parse(statsSegmentStr);
console.log("statsSegment", statsSegmentObj);
console.log("statsSegment.stats ", statsSegmentObj.ApiJSONObject.stats);
const stat = statsSegmentObj.ApiJSONObject.stats.find(x => x.metadata.name === value);
if (stat) {
return stat.value;
}
}
let result = getStatsFields(value,statsSegmentJson);
console.log(result);

Need to make on object in Javascript based on an existing object which is efficient considering its performance

{
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"column_0": {
"value": "1",
"label": "name"
},
"condition_0": {
"value": "101",
"label": "Is equal to"
},
"column_1": {
"value": "2",
"label": "age"
},
"condition_1": {
"value": "102",
"label": "Is less than"
}
}
I have the above object in JavaScript. From this object I need to create the following object. Need to find a way which is good from performance point of view. The below conditions array is based on the object starting with 'column_' in the above object.
For example: if there are column_0, column_1, column_2, the length of conditions array will be 3. These columns will be coming dynamically, can be from 0-n, n = any integer >= 0. (i.e. column_0 - column_n)
The same condition applies for condition_0, condition_1. Also, condition_0 is always associated with column_0, condition_1 is always associated with column_1 ans so on.
{
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"conditions" : [
{
"column_id": 1, // column_0.value
"column_name": "name", // column_0.label
"condition_id": 101 // condition_0.value
},
{
"column_id": 2, // column_1.value
"column_name": "age", // column_1.label
"condition_id": 102 // condition_1.value
}
],
}
extract the conditions using ...rest, reduce the Object.entries , construct the data structure and push it to the resulting array, finally put everything back together :
const data = {
"name": "test name",
"description": "test desc",
"data_table_id": 3,
"column_0": {
"value": "1",
"label": "name"
},
"condition_0": {
"value": "101",
"label": "Is equal to"
},
"column_1": {
"value": "2",
"label": "age"
},
"condition_1": {
"value": "102",
"label": "Is less than"
}
}
const {
name,
description,
data_table_id,
...rest
} = data;
const conditions = Object.entries(rest).reduce((all, [key, obj]) => {
if (key.startsWith('condition')) {
const id = key.split('_')[1];
const condition = {
"column_id": rest[`column_${id}`].value,
"column_name": rest[`column_${id}`].label,
"condition_id": obj.value,
}
all.push(condition)
}
return all;
}, []);
const result = {
name,
description,
data_table_id,
conditions
}
console.log(result)

Categories