Reputation: 111
Updated object keys
let conditionedObject = {
"isNameRequired": true,
"isCityRequired": false,
"isPostRequired": true
};
let myTotalData = {
data: {
"givenName": 'myname',
"street":"mystreet",
"cityName": 'mycity',
"postcode": 'mypost'
}
};
let resultData = {};
Both condionedObject and myTotalData comes from different source.
I would like to know the best way to create a new object based on the condionedObject,
example my condionedObject says I need only name and post so my resultData
should return {"givenName":"myname","postcode":"mypost"}
conditionedObject.isNameRequired is for myTotalData.data.givenName, conditionedObject.isPostRequired is for myTotalData.data.postcode, conditionedObject.isCityRequired is for myTotalData.data.cityName, all this will say whether myTotalData key is required to be placed in the new object.
Thanks in advance for all the suggestions and helps
Upvotes: 0
Views: 528
Reputation: 3030
Here is my solution:
You need to change the keys in the object conditionedObject
and remove the is-
prefix so that they are the same as the keys in myTotalData
. This way the check is easier later.
Then it's pretty straight-forward.
let conditionedObject: {[key: string]: boolean} = {
"isName": true,
"isCity": false,
"isPost": true
};
type DataType = {[key: string]: string};
let myTotalData: DataType = {
"name": 'myname',
"city": 'mycity',
"post": 'mypost'
};
let resultData: DataType = {};
for(const key in conditionedObject) {
// Ensure that the key is really part of this object
if(!conditionedObject.hasOwnProperty(key)) {
continue;
}
if(!conditionedObject[key]) {
continue;
}
const dataKey = key.startsWith("is")
? key.charAt(2).toLowerCase() + key.substring(3)
: key;
if(myTotalData.hasOwnProperty(dataKey)) {
resultData[dataKey] = myTotalData[dataKey];
}
}
console.log(resultData);
Output:
{
name: "myname",
post: "mypost"
}
Upvotes: 1
Reputation: 13078
You can use Array.prototype.reduce():
In this case I recommend you to create a new object to store the relationship between properties:
let conditionedObject = {
"isNameRequired": true,
"isCityRequired": false,
"isPostRequired": true
};
let myTotalData = {
data: {
"givenName": 'myname',
"street":"mystreet",
"cityName": 'mycity',
"postcode": 'mypost'
}
};
const reference = {
"isNameRequired": "givenName",
"isCityRequired": "cityName",
"isPostRequired": "postcode"
}
let resultData = {};
resultData =Object.entries(conditionedObject).reduce((obj, [key, value]) => {
if(value && myTotalData.data[reference[key]]) {
const prop = reference[key];
obj[prop] = myTotalData.data[prop];
}
return obj;
}, {});
console.log(resultData);
Upvotes: 1
Reputation: 3307
You can use something like that, if you can be sure that the conditionedObject
keys are always equal your myTotalData
keys, but capitalized and with "is" on the front:
let capitalize = str => str.charAt(0).toUpperCase() + str.slice(1)
let prependIs = str => "is" + str
let conditionedObject = {
"isName": true,
"isCity": false,
"isPost": true
};
let myTotalData = {
"name": 'myname',
"city": 'mycity',
"post": 'mypost'
};
let filterData = (data, conditionObj) => Object.fromEntries(Object.entries(data)
.filter(([key, _]) => conditionObj[prependIs(capitalize(key))]))
// More verbose alternative for browsers which doesn't support `Object.fromEntries()`
let filterDataAlt = (data, conditionObj) => {
let result = {}
let filteredEntries = Object.entries(data)
.filter(([key, _]) => conditionObj[prependIs(capitalize(key))])
for (let [key, value] of filteredEntries) {
result[key] = value
}
return result
}
console.log(filterData(myTotalData, conditionedObject))
console.log(filterDataAlt(myTotalData, conditionedObject))
Upvotes: 0