Convert dynamic string to JSON using javascript - javascript

I am using API that its response contains dynamic array of strings as the following:
var arr = ["Request.name","Request.name.first","Request.name.first.last"]; //response 3
so i want to convert it dynamically to array of JSON objects like this:
var arrayOfObjects = [
{
"Request": {
"name":val
}
} //converted from arr[0]
,{
"Request": {
"name":{
"first":val
}
}
} //converted from arr[1]
,{
"Request": {
"name":{
"first":{
"last":val
}
}
}
} //converted from arr[2]
];
and so on...
is this possible?

You can create a function that converts a dot-separated string into a respective deeply nested object, then map your input array of strings with it. My solution is iterative, though I think it can be done recursively as well.
var arr = ["Request.name","Request.name.first","Request.name.first.last"];
function createObjFromStr(str) {
return str.split('.').reduceRight((all, key, i, arr) => {
if (i === arr.length - 1) {
all = {[key]: 0};
} else {
all[key] = Object.assign({}, all);
Object.keys(all).forEach(k => {
if (k !== key) delete all[k];
});
}
return all;
}, {});
}
const arrayOfObjects = arr.map(createObjFromStr);
console.log(arrayOfObjects);

Related

Remove underscore prefixes from all keys

I have data that looks like the following:
[
{
"_sourceAddresses":[
{
"_street1":"957 Heathcote Unions",
"_city":"Matteoside",
"_state":"Hawaii",
"_postalCode":"69680",
"_postalCodePlusFour":"7715",
"_country":"USA",
"_type":0,
"_updatedAt":"1991-03-10T22:34:27.000Z",
"_createdAt":"1970-07-24T09:34:12.000Z"
}
],
"_emails":[
{
"_address":"labadie.gwendolyn#gmail.com",
"_primary":true
}
],
"_phoneNumbers":[
{
"_number":"4612902836",
"_type":0,
"_carrier":"AT&T"
}
],
"_customFields":{
},
"_active":true,
"_firstName":"Haven",
"_lastName":"Runolfsdottir",
"_gender":"M",
"_sourceIndividualId":"c1126d05-0e5b-4da1-8535-e1061d4163ee",
"_sourceCampusId":"ae1e70d5-d8bf-4942-b9ea-3da5765e055f",
"_primaryContact":true,
"_salutation":"Mrs.",
"_suffix":"DDS",
"_birthDate":"1989-02-16T10:06:25.000Z"
},
{
"_sourceAddresses":[
{
"_street1":"5910 Langosh Burgs Apt. 281",
"_city":"West Katheryn",
"_state":"Arkansas",
"_postalCode":"49571",
"_postalCodePlusFour":null,
"_country":"USA",
"_type":0,
"_updatedAt":"1984-01-09T09:34:02.000Z",
"_createdAt":"1986-01-13T17:36:41.000Z"
}
],
"_emails":[
{
"_address":"labadie_cristopher#yahoo.com",
"_primary":true
}
],
"_phoneNumbers":[
{
"_number":"0608405498",
"_type":0,
"_carrier":"Verizon"
}
],
"_customFields":{
},
"_active":true,
"_firstName":"Andreane",
"_lastName":"Kerluke",
"_gender":"F",
"_sourceIndividualId":"0726bfc2-56af-4e46-90ef-c0a286404334",
"_sourceCampusId":"86fdb656-7e29-4ace-a1c7-149db81c7f5e",
"_primaryContact":true,
"_salutation":"Mrs.",
"_suffix":null,
"_birthDate":"1979-11-14T10:07:02.000Z"
}
]
When it is saved as JSON, I'd like to remove the underscores in the keys. Is there an easy way to do this?
I have tried unsuccessfully to adapt this code to accomplish it:
Replace dot to underscore in js object keys names
function removeLeadingUnderscores(obj) {
_.forOwn(obj, (value, key) => {
if (_.startsWith("_")) {
const cleanKey = _.substring(1)
obj[cleanKey] = value;
delete obj[key];
}
// continue recursively looping through if we have an object or array
if (_.isObject(value)) {
return removeLeadingUnderscores(value);
}
});
return obj;
}
Since you're planning to save as JSON already, you can use its naturally recursive nature with its reviver parameter to return objects without the underscores. Map the entries of the object to a new object without the leading _.
const arr=[{_sourceAddresses:[{_street1:"957 Heathcote Unions",_city:"Matteoside",_state:"Hawaii",_postalCode:"69680",_postalCodePlusFour:"7715",_country:"USA",_type:0,_updatedAt:"1991-03-10T22:34:27.000Z",_createdAt:"1970-07-24T09:34:12.000Z"}],_emails:[{_address:"labadie.gwendolyn#gmail.com",_primary:!0}],_phoneNumbers:[{_number:"4612902836",_type:0,_carrier:"AT&T"}],_customFields:{},_active:!0,_firstName:"Haven",_lastName:"Runolfsdottir",_gender:"M",_sourceIndividualId:"c1126d05-0e5b-4da1-8535-e1061d4163ee",_sourceCampusId:"ae1e70d5-d8bf-4942-b9ea-3da5765e055f",_primaryContact:!0,_salutation:"Mrs.",_suffix:"DDS",_birthDate:"1989-02-16T10:06:25.000Z"},{_sourceAddresses:[{_street1:"5910 Langosh Burgs Apt. 281",_city:"West Katheryn",_state:"Arkansas",_postalCode:"49571",_postalCodePlusFour:null,_country:"USA",_type:0,_updatedAt:"1984-01-09T09:34:02.000Z",_createdAt:"1986-01-13T17:36:41.000Z"}],_emails:[{_address:"labadie_cristopher#yahoo.com",_primary:!0}],_phoneNumbers:[{_number:"0608405498",_type:0,_carrier:"Verizon"}],_customFields:{},_active:!0,_firstName:"Andreane",_lastName:"Kerluke",_gender:"F",_sourceIndividualId:"0726bfc2-56af-4e46-90ef-c0a286404334",_sourceCampusId:"86fdb656-7e29-4ace-a1c7-149db81c7f5e",_primaryContact:!0,_salutation:"Mrs.",_suffix:null,_birthDate:"1979-11-14T10:07:02.000Z"}];
const stringified = JSON.stringify(
arr,
(_, value) => {
return value && typeof value === 'object' && !Array.isArray(value)
? Object.fromEntries(
Object.entries(value)
.map(([key, value]) => [key.slice(1), value])
)
: value;
}
);
console.log(stringified);
If some properties don't start with _, you can change .slice(1) to .replace(/^_/, '').
Here's a simplified version of saving the object with removed underscores through simple recursive logic:
let savedJson: any = [];
renamingArray(obj); // obj is your object
function renamingArray(element: any){
for(let element of obj)
if (Object.prototype.toString.call(element) === '[object Array]') {
renamingArray(element);
else
renamingObject(element);
}
}
function renamingObject(obj: any){
let keys = Object.keys(obj)
for(let objectKey of keys){
savedJson.push({ [objectKey.substring(1)]: obj[objectKey] });
}
}
console.log(savedJson)

Nested Array Of JSON Looping in Typescript

I'm trying to get the value of "id" of the below mentioned array of json but i'm not able to get the result because it is surrounded by two "[[" array braces, can anybody please help me out, Also im getting these array of JSON from another loop if the loop runs single time i'm getting single array brace "[" , if the loop runs multiple times i'm gettin "[[" braces...
[
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
I'm calling this function to get the JSON objects in the above array...
var getAllValuesOfKey = function (dataObj, queryKey) {
var resultArr = [];
if (!queryKey) {
return resultArr;
}
function execute(dataObj, queryKey) {
Object.keys(dataObj).forEach(function (key, index) {
if (typeof dataObj[key] == 'object' && !(dataObj[key] instanceof Array)) {
if (key == queryKey) {
resultArr.push(dataObj[key]);
}
execute(dataObj[key], queryKey);
} else if (key == queryKey) {
resultArr.push(dataObj[key]);
}
});
}
execute(dataObj, queryKey);
return resultArr;
}
var searchKey = 'task';
var result=getAllValuesOfKey(obj1, searchKey);
You can select the inner array in your loop with index 0 on the outer array, like this:
var myDoubleArray: any = [[{...}, {...}, {...}]];
for (let i = 0; i < myDoubleArray[0].length; i++) {
console.log(myDoubleArray[0][i].attributes.id);
}
If the arrays are still in JSON format, you need to first parse them to JavaScript before you can loop through the data. This can be done with JSON.parse().
var arr = [
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
for (var i in arr[0]) {
//arr[0][i].attributes.id will give you the id
console.log(arr[0][i].attributes.id);
}

return value after filtering array inside an object of arrays

I am trying to create an autocomplete which returns an array of objects using a function. My Object is something like:
this.vehiclesList =
[
{
"additionalDriverContacts": [9929929929, 9992992933, 9873773777],
"id": 1
},
{
"additionalDriverContacts": [8388388388, 8939939999],
"id": 2
}
]
I want to filter the array based on additionalDriverContacts .
My function goes like this:
filterVehicleAdditionalMobile(val: string) {
if (typeof val != 'string') {
return [];
}
let value= val? this.vehiclesList.filter((item) => {
if(item.additionalDriverContacts)
item.additionalDriverContacts.forEach((option)=> {
String(option).toLowerCase().indexOf(val.toLowerCase()) != -1
})
}
}) : this.vehiclesList;
console.log(value)
return value;
}
But in the console value is coming empty array. Where did I go wrong. I tried looking for the solution in this question How do i filter an array inside of a array of objects?
but it didnot help as my usecase is different.
My desired Result should be like:
If 99299 is passed as an argument to the function , then additionalDriverContacts matching that number should be return as an array.
for input 99299, result = [9929929929,9992992933] should be returned
for input 99299, result = [9929929929,9992992933] should be returned
We can use array .map() to extract contacts, then filter down with string .search():
const vehiclesList = [
{"id": 1, "additionalDriverContacts": [9929929929, 9992992933, 9873773777]},
{"id": 2, "additionalDriverContacts": [8388388388, 8939939999]}]
result = getMatchingContacts(vehiclesList, 99299) // run test
console.log(result) // show result
function getMatchingContacts(list, key) {
const arrayOfContacts = list.map(item => item.additionalDriverContacts)
const contacts = [].concat(...arrayOfContacts) // flatten the nested array
.filter(contact => contact.toString().search(key.toString()) >= 0) // find matches
return contacts
}
Hope this helps.
Cheers,
So what you need to do here is first transform each of the items in vehiclesList into an array of matching results, and then concatenate those together.
Give this a try:
var vehiclesList = [{
"additionalDriverContacts": [9929929929, 9992992933, 9873773777],
"id": 1
},
{
"additionalDriverContacts": [8388388388, 8939939999],
"id": 2
}
];
function filterVehicleAdditionalMobile(val) {
if (typeof val != 'string') {
return [];
}
// array of arrays
const values = vehiclesList.map((item) => {
if (!item.additionalDriverContacts) { return []; }
return item.additionalDriverContacts.filter((option) =>
String(option).toLowerCase().indexOf(val.toLowerCase()) != -1
);
});
console.log(values);
// flatten
return Array.prototype.concat.apply([], values);
}
console.log(filterVehicleAdditionalMobile('99'));
Alternatively, you could concatenate all of the items together and then filter them. This is less efficient, but simpler and less code:
var vehiclesList = [{
"additionalDriverContacts": [9929929929, 9992992933, 9873773777],
"id": 1
},
{
"additionalDriverContacts": [8388388388, 8939939999],
"id": 2
}
];
function flatten(values) {
return Array.prototype.concat.apply([], values);
}
function filterVehicleAdditionalMobile(val) {
if (typeof val != 'string') {
return [];
}
return flatten(vehiclesList.map(v => v.additionalDriverContacts || []))
.filter(option => String(option).toLowerCase().indexOf(val.toLowerCase()) != -1);
}
console.log(filterVehicleAdditionalMobile('99'));
Updated : With the last edit of the question
try to change by :
filterVehicleAdditionalMobile(val: string) {
if (typeof val !== 'string') {
return [];
}
let driverContacts = [];
this.vehiclesList.forEach((vehicule) => {
if (vehicule.additionalDriverContacts) {
if (val) {
driverContacts = driverContacts.concat(vehicule.additionalDriverContacts.filter((driverContact) => {
return String(driverContact).toLowerCase().indexOf(val.toLowerCase()) !== -1;
}));
} else {
driverContacts = driverContacts.concat(vehicule.additionalDriverContacts);
}
}
});
return driverContacts;
}
Test :
const driver = this.filterVehicleAdditionalMobile('8');
console.log(driver);
Display :
0: 9873773777
1: 8388388388
2: 8939939999

Javascript - Parsing INI file into nested associative array

I'm new to Javascript and I'm having trouble parsing an INI formatted file into nested objects.
The file I have is formatted like this:
ford.car.focus.transmission=standard
ford.car.focus.engine=four-cylinder
ford.car.focus.fuel=gas
ford.car.taurus.transmission=automatic
ford.car.taurus.engine=V-8
ford.car.taurus.fuel=diesel
purchased=Ford Taurus
I would like to have the structure look like this:
{ ford:
{ car:
{ focus:
{
transmission: 'standard',
engine: 'four-cylinder',
fuel: 'gas'
}
}
{ taurus:
{
transmission: 'automatic',
engine: 'V-8',
fuel: 'diesel'
}
}
}
purchased: 'Ford Taurus'
}
I'm storing the file in lines in an array, splitting on '\n'. I'm trying to write a method that would be called in a loop, passing my global object like this:
var hash = {};
var array = fileData.toString().split("\n");
for (i in array) {
var tmp = array[i].split("=");
createNestedObjects(tmp[0], tmp[1], hash);
}
This should let me access the values in the hash object like:
hash.ford.car.focus.fuel
# 'gas'
hash.purchase
# 'Ford Taurus'
I've tried something like what was suggested here: Javascript: how to dynamically create nested objects using object names given by an array, but it only seems to set the last item in the nest.
{ fuel: 'diesel',
purchased: 'Ford Taurus' }
My unsuccessful attempt looks like this:
createNestedObjects(path, value, obj) {
var keys = path.split('.');
keys.reduce(function(o, k) {
if (k == keys[keys.length-1]) {
return o[k] = value;
} else {
return o[k] = {};
}
}, obj);
}
However, it will only return the last value for the nested values:
{ ford: { car: { taurus: { fuel: 'diesel' } } },
purchased: 'Ford Taurus' }
The function needs to check whether an intermediate key already exists before assigning to it.
createNestedObjects(path, value, obj) {
var keys = path.split('.');
keys.reduce(function(o, k) {
if (k == keys[keys.length-1]) {
return o[k] = value;
} else if (o[k]) {
return o[k];
} else {
return o[k] = {};
}
}, obj);
}

Return JSON properties

I am trying to return my JSON object's properties. My JSON file object looks like:
{ Products:
{
'Cars': { tableFields: [Object] },
'Planes': { tableFields: [Object] }
}
}
I am trying to return an array that contains Products' attributes - Cars and Planes. For example - I want the end result to be the following array:
['Cars', 'Planes']
Can someone help?
Thanks!
You can use Object.keys() function:
var data = {
Products: {
'Cars': {
tableFields: [ Object ]
},
'Planes': {
tableFields: [ Object ]
}
}
};
var result = Object.keys(data.Products);
console.log(result);
var keys = [];
for ( var key in Products )
{
//We only want the direct properties
if ( Products.hasOwnProperty( key ) ) keys[ keys.length ] = key;
}

Categories

Resources