I want to create multiple JSON files from an array.
Array :
[{
"Reference": "Registration",
"langkey": "REG_LBL",
"English": "Company Registration",
"Japanese": "会社登録"
}, {
"Reference": "Registration",
"langkey": "INFO_LBL",
"English": "Company Information",
"Japanese": "会社情報"
}]
I need to create two JSON files name English and Japanese(it will be dynamic) from above array.
Desired Output
English.json
{
'INFO_LBL' : 'Company Information',
'REG_LBL':'Company Registration'
}
Japanese.json
{
'INFO_LBL' : '会社情報',
'REG_LBL':'会社情報'
}
Code
for (var i = 0; i < data.length; i++) {
var obj = data[i];
for (var key in obj) {
if (key !=='Reference' && key !== 'langkey' ) {
//{'REG_LBL':'Company Registration'}
objects[obj['langkey']] = obj[key];
fs.writeFileSync('lang/' + langkey + '.json', JSON.stringify(objects, null, 2), { encoding: 'utf8' }, function (err) {
if (err)
{ throw err; }
console.log("completed")
});
}
}
}
I am ale to create two JSON files but the content is overwritten by another.Please help to resolve this?
var finalObject = {};//create new object
data.forEach(v => {
var langkey = v.langkey;
Object.keys(v).forEach(val => {
if (val != 'langkey' && val != 'Reference') {
if (finalObject[val]) {//find if language object is already created.If already created insert in it else create new
let data = {};
data[langkey] = v[val]
finalObject[val] = Object.assign(finalObject[val], data)
} else {
finalObject[val] = {};
finalObject[val][langkey] = v[val];
}
}
})
})
Object.keys(finalObject).forEach(key => {
fs.writeFileSync(path.join(__dirname, `/lang/${key}.json`), JSON.stringify(finalObject[key], null, 2), (err) => {
if (err)
{ throw err; }
console.log('completed');
});
})
You have 2 items in your array, and 2 languages both so do you need to have 4 json files? 2 for INFO_LBL (English & japanesh) and 2 for REG_LBL(English & japanesh) ? or do you just need 2 json files for the second item INFO_LBL (English & japanesh) ?
update: bellow is your solution
for (var i = 0; i < data.length; i++) {
var obj = data[i];
for (var key in obj) {
if (key !== 'Reference' && key !== 'langkey') {
var newObject = {};
var path = 'lang/' + key + '.json';
if (fs.existsSync(path)) {
var newObject = JSON.parse(fs.readFileSync(path, 'utf8'));
}
newObject[obj.langkey] = obj[key];
fs.writeFileSync(path, JSON.stringify(newObject, null, 2), { encoding: 'utf8' });
}
}
}
This one works. I created separate objects for each using window['newVariable'];
var myArray =
[{
"Reference": "Registration",
"langkey": "REG_LBL",
"English": "Company Registration",
"Japanese": "会社登録"
}, {
"Reference": "Registration",
"langkey": "INFO_LBL",
"English": "Company Information",
"Japanese": "会社情報"
}];
for(i=0; i<myArray.length; i++){
window['myJSON' + i] = myArray[i];
}
console.log(myJSON0, myJSON1);
Here's what I got, two separate objects
Now all you have to do is stringify to JSON.
If your data is getting overwritten, it would be because of the writeFileSync. You should be using appendFileSync or the a flag for writeFileSync
Related
Trying to derive Full JPATH if Object is an Array.
Running below code,
var INPUT = ['ADDR.ADDR_L1','NAME.FIRST_NAME','CONTACT.TYPE','LEVEL1OBJ.LEVEL2OBJ','LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ'];
var obj = {
"ID":"1",
"NAME":{"FIRST_NAME":"ABC","LAST_NAME":"XYZ"},
"ADDR":
[{"TYPE":"HOME",
"ADDR_L1":"SDGSG",
"CITY":"AFAFA"},
{"TYPE":"OFFC",
"ADDR_L1":"AFASF",
"CITY":"SDGSDG"}],
"CONTACT":
[{"TYPE":"A"},{"TYPE":"B"},{"TYPE":"C"}],
"LEVEL1OBJ":{"LEVEL2ARR":[
{"LEVEL3OBJ":"A"},
{"LEVEL3OBJ":"B"}],
"LEVEL2OBJ":"GFDB"
}
};
var jpath1=[];
var jpath_final=[];
for ( var i=0;i<INPUT.length;i++)
{ // Loop over the list of JPATH coming in as INPUT
jpath1=[];
console.log("I"+i);
var jpath = INPUT[i].split('.'); //Splitting keys in an array
console.log(jpath);
for ( var j=0;j<jpath.length;j++)
{ //loop over all keys in input
console.log("J"+j);
var subjpath=jpath[j];
console.log(jpath.length);
console.log(subjpath);
for ( var key of Object.keys(obj) ) //getting all keys on obj
{
console.log("KEY");
console.log(key);
if ( Object.prototype.toString.call(obj[key]) === '[object Array]' && subjpath == key ) //if object is an array
{
console.log("yes");
console.log(obj[key].length);
for ( var k=0;k<obj[key].length;k++)
{ //looping over all array index
console.log("k"+k);
jpath1.push(subjpath+'.'+k); //appending array index to original jpath
console.log(jpath1);
}
}
else if ( key == subjpath )
{
jpath1.push(subjpath);
subjpath="";
}
}
}
//appending other objects after array object
jpath1.forEach((element, index) => {
jpath1[index] = element + '.' + subjpath;
});
console.log(jpath1);
jpath_final.push(jpath1);
console.log(jpath_final);
}
Current Output:
[
[ 'ADDR.0.ADDR_L1', 'ADDR.1.ADDR_L1' ],
[ 'NAME.FIRST_NAME' ],
[ 'CONTACT.0.TYPE', 'CONTACT.1.TYPE', 'CONTACT.2.TYPE' ],
[ 'LEVEL1OBJ.LEVEL2OBJ' ],
[ 'LEVEL1OBJ.LEVEL3OBJ' ] --Incorrect
]
The process is working for scenario where Array Object is first level. But not working for 2nd Level onwards array object. I know i need to perform it recursively but corrupting the result if I take out Object.keys loop as function.
Expected Output
[
[ 'ADDR.0.ADDR_L1', 'ADDR.1.ADDR_L1' ],
[ 'NAME.FIRST_NAME' ],
[ 'CONTACT.0.TYPE', 'CONTACT.1.TYPE', 'CONTACT.2.TYPE' ],
[ 'LEVEL1OBJ.LEVEL2OBJ' ],
[ 'LEVEL1OBJ.LEVEL2ARR.0.LEVEL3OBJ' ,'LEVEL1OBJ.LEVEL2ARR.1.LEVEL3OBJ' ]
]
Meanwhile I tried something more which gives close to what i needed,
var INPUT = ['ADDR.ADDR_L1','NAME.FIRST_NAME','CONTACT.TYPE','LEVEL1OBJ.LEVEL2OBJ','LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ'];
var obj = {
"ID":"1",
"NAME":{"FIRST_NAME":"ABC","LAST_NAME":"XYZ"},
"ADDR":
[{"TYPE":"HOME",
"ADDR_L1":"SDGSG",
"CITY":"AFAFA"},
{"TYPE":"OFFC",
"ADDR_L1":"AFASF",
"CITY":"SDGSDG"}],
"CONTACT":
[{"TYPE":"A"},{"TYPE":"B"},{"TYPE":"C"}],
"LEVEL1OBJ":{"LEVEL2ARR":[
{"LEVEL3OBJ":"A"},
{"LEVEL3OBJ":"B"}],
"LEVEL2OBJ":"GFDB"
}
};
var jpath_final=[];
function append_index(jp,index)
{
if ( jpath_final[i] == null )
{
jpath_final[i] = jp+'.'+index;
}
else
{
jpath_final[i] += '.'+jp+'.'+index;
}
return;
}
function append_jpath(jp)
{
if ( jpath_final[i] == null )
{
jpath_final[i] = jp;
}
else
{
jpath_final[i] += '.'+jp;
}
return;
}
function chk_func ( obj,jpath )
{
for ( var key of Object.keys(obj) )
{
console.log("Print Key:"+key);
console.log("JPATH "+jpath);
console.log("J " + j);
if ( j == jpath.length-1 )
{
console.log("Enter 1st if");
append_jpath(jpath[j]);
j++;
console.log("JPATH "+ jpath_final[i]);
return;
}
else
{
if ( typeof obj[key] == 'object' && key == jpath[j] && Object.prototype.toString.call(obj[key]) != "[object Array]")
{
console.log("Enter 2nd if");
console.log( jpath[j] + " is Object");
append_jpath(jpath[j]);
console.log( "JPATH "+jpath_final[i]);
j++;
console.log("Now Object "+ key+" "+jpath[j] );
chk_func(obj[key],jpath);
break;
}
else if ( Object.prototype.toString.call(obj[key]) === "[object Array]" && key == jpath[j] )
{
console.log("Enter 3rd if");
console.log("jpath "+jpath);
console.log("key "+key);
console.log(jpath[j] + " is Array");
append_index(jpath[j],obj[key].length);
console.log("JPATH "+jpath_final[i]);
return;
}
else
{
continue;
}
}
}
return;
}
for ( var i=0;i<INPUT.length;i++)
{
console.log("i:"+i);
var jpath = INPUT[i].split('.');
console.log(jpath);
for ( var j=0;j<jpath.length;j++)
{
console.log("j:"+j);
console.log(jpath[j]);
if ( j < jpath.length-1 && jpath[j] != undefined )
{
chk_func(obj,jpath);
}
else
{
append_jpath(jpath[j]);
console.log("JPATH "+ jpath_final[i]);
}
}
}
console.log("final "+jpath_final);
I think the entry point of your recursion is likely where you are stumbling. If you'll move all of your processing into the recursive block, then you can process from a top-down approach in your object. This also allows you to peel off layers of the object for processing as you navigate through the split path (INPUT array).
There are a few other changes in the following to be a little more efficient, and I changed a few variable names to help me keep things straight as I was debugging.
var INPUT = [ "ADDR.ADDR_L1", "NAME.FIRST_NAME", "CONTACT.TYPE", "LEVEL1OBJ.LEVEL2OBJ", "LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ"];
var main_obj = {
ID: "1",
NAME: { FIRST_NAME: "ABC", LAST_NAME: "XYZ" },
ADDR: [
{ TYPE: "HOME", ADDR_L1: "SDGSG", CITY: "AFAFA" },
{ TYPE: "OFFC", ADDR_L1: "AFASF", CITY: "SDGSDG" }
],
CONTACT: [{ TYPE: "A" }, { TYPE: "B" }, { TYPE: "C" }],
LEVEL1OBJ: {
LEVEL2ARR: [{ LEVEL3OBJ: "A" }, { LEVEL3OBJ: "B" }],
LEVEL2OBJ: "GFDB"
}
};
var json_final = [];
for (var keyInput of INPUT) {
processKeys(keyInput, main_obj, keyInput);
}
console.log(JSON.stringify(json_final));
function processKeys (keyInp, obj, rootKeyInp) {
if (keyInp.includes('.')) {
var tokens = keyInp.split('.');
if (1 < tokens.length) {
console.log(tokens[0] + ' :: ' + rootKeyInp);
var keyInp0 = tokens.shift();
if (obj[keyInp0] != null) {
processKeys(tokens.join('.'), obj[keyInp0], rootKeyInp);
}
}
} else {
var json_arr_tmp = [];
if (Object.prototype.toString.call(obj) === "[object Array]") {
for (var i = 0; i < obj.length; i++) {
let rootKeyInpSuffix = rootKeyInp.slice(-(keyInp.length + 1));
json_arr_tmp.push(rootKeyInp.substr(0, rootKeyInp.lastIndexOf(rootKeyInpSuffix)) + '.' + i + rootKeyInpSuffix);
}
} else {
json_arr_tmp.push(rootKeyInp);
}
json_final.push(json_arr_tmp);
}
}
How to create dynamic JSON as per input. Filter data and create appropriate JSON objects key and values pairs
Below is the database.
Below is the code which had tried but won't work...
success: function (data) {
//lenght
data.value.length
// console.log(data);
//HC list JSON
empData = '[';
$.each(data.value, function (index, item) {
var dataLen = data.value.length;
empData += `{`
if (item.STATUS == 'Active') {
if (item.NODE == 'Testing') {
empData += `"DDM_CO2" : {
"DESIGNATION": "${item.DESIGNATION}",
"EMPLOYMENT": "${item.EMPLOYMENT}",
"GENDER": "${item.GENDER}",
"Name1": "${item.Name1}",
"ROLE": "${item.ROLE}"
},`
} else if (item.NODE == 'Devlopment') {
empData += `"GPH" : {
"DESIGNATION": "${item.DESIGNATION}",
"EMPLOYMENT": "${item.EMPLOYMENT}",
"GENDER": "${item.GENDER}",
"Name1": "${item.Name1}",
"ROLE": "${item.ROLE}"
}`
}
}
});
empData += ']';
empData = JSON.parse(empData);
console.log(empData);
//HC list JSON END
},
Something like this should work
function (data) {
//create array to store emp objects
var empData = new Array();
$.each(data.value, function (index, item) {
if (item.STATUS == 'Active') {
if (item.NODE == 'Testing') {
//create custom object
var emp = {
DDM_CO2: {
DESIGNATION: item.DESIGNATION,
EMPLOYMENT: item.EMPLOYMENT
//etc: item.etc
//etc: item.etc
//etc: item.etc
}
};
//add to array
empData.push(emp);
} else if (item.NODE == 'Devlopment') {
var emp = {
GPH: {
DESIGNATION: item.DESIGNATION,
EMPLOYMENT: item.EMPLOYMENT,
GENDER: item.GENDER,
Name1: item.Name1,
ROLE: item.ROLE
}
};
empData.push(emp);
}
}
}
I have a keys property that is related to map property. The length of keys correspond with how deep the level of each map property goes. In this case only 2 levels.
If I add another entry to keys then each map property will go one more level deeper.
Below is the data
{
keys: [
"vendorApNbr",
"type"
],
map: {
_default: { <-** 1st level
_default: "'100026'", <-** 2nd level
PT_CC: "'120035'", <-** 2nd level
PT_DC: "'120037'"
},
A-00: { <- ** 1st level
_default: "'120037'" <- ** 2nd level
},
A-01: {
_default: "'120035'"
},
A-02: {
_default: "'120035'"
},
A-03: {
_default: "'120036'"
},
A-04: {
_default: "'100024'"
}
}
}
I would like to create an array of arrays where each item in the array is iteration of going from level 1 to level 2 (but can go down more levels if needed)
i.e.
[
['_default', '_default', "'10026'"],
['_default', 'PT_CC', "'120035'"],
['_default', 'PP_DC', "'120037'"],
['A-00', '_default', "'120037'"],
['A-01', '_default', "'120035'"],
...etc
['A-04', '_default', "'100024'"]
]
I'm limited to ES5 or lodash. I'm thinking of recursion but not sure how to approach this. Any suggestion can help.
Edit
also to have a way to turn the array form back to nested object form
What about this? It doesn't care about how many nested the object is and what the level is. Additionally, each depth could be different.
var obj = {
"_default": {
"_default": "'100026'",
"PT_CC": "'120035'",
"PT_DC": "'120037'"
},
"A-00": {
"_default": "'120037'"
},
"A-01": {
"_default": "'120035'"
},
"A-02": {
"_default": "'120035'"
},
"A-03": {
"_default": "'120036'"
},
"A-04": {
"_default": "'100024'"
}
}
var result = [];
function rec(acc, obj) {
if (typeof obj === "object") {
for (var key in obj) {
rec(acc.concat([key]), obj[key]);
}
return;
}
result.push(acc.concat([obj]));
}
rec([], obj);
console.log(result);
You can do it by using Depth-Fist Search.
The code below is an example extracted from this webpage. The difference here is that is concatenates every key, but you can use the same algorithm with some modifications to get a list.
var obj = {
baz: {
foo: {
bar: "5"
},
hell: {
sin: "0"
}
},
a: {
b: "1"
}
};
var hash = {};
var str = '';
var dfs = function(obj, str) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'string')
hash[str + key] = obj[key];
else {
dfs(obj[key], str + key + '.');
}
}
}
};
dfs(obj, str);
console.log(hash);
You can use the following recursive function to flatten the object's properties in an array.
This function...
only takes one parameter as argument and
doesn't rely on external vars
var data = {
keys: [
"vendorApNbr",
"type"
],
map: {
_default: {
_default: "'100026'",
PT_CC: "'120035'",
PT_DC: "'120037'"
},
A00: {
_default: "'120037'"
},
A01: {
_default: "'120035'"
},
A02: {
_default: "'120035'"
},
A03: {
_default: "'120036'"
},
A04: {
_default: "'100024'"
}
}
};
function makeItFlat(data) {
var newArray = [];
var properties = Object.getOwnPropertyNames(data);
for (var prop of properties) {
if (typeof data[prop] === 'object') {
var flat = makeItFlat(data[prop]);
for (var f of flat) {
if (!Array.isArray(f)) {
f = [f];
}
newArray.push([prop].concat(f));
}
} else {
newArray.push([prop].concat([data[prop]]));
}
}
return newArray;
}
var flatArray = makeItFlat(data.map);
console.log(flatArray);
For converting the array back to the original object, you can use this code:
var flatArray = [
["_default", "_default", "'100026'"],
["_default", "PT_CC", "'120035'"],
["_default", "PT_DC", "'120037'"],
["A00", "_default", "'120037'"],
["A01", "_default", "'120035'"],
["A02", "_default", "'120035'"],
["A03", "_default", "'120036'"],
["A04", "_default", "'100024'"]
];
function convertArrayOfStringsToObject(flatArray) {
var newObject = {};
var key = flatArray[0];
var entry = null;
if (flatArray.length == 2) {
entry = flatArray[1];
} else {
entry = convertArrayOfStringsToObject(flatArray.slice(1));
}
if (key in newObject) {
//key exists already, then merge:
Object.assign(newObject[key], entry);
} else {
newObject[key] = entry;
}
return newObject;
}
function expandArray(flatArray) {
var newObject = {}
for (var line of flatArray) {
var key = line[0];
var entry = convertArrayOfStringsToObject(line.slice(1));
if (key in newObject) {
//key exists already, then merge:
Object.assign(newObject[key], entry);
} else {
newObject[key] = entry;
}
}
return newObject;
}
console.log(expandArray(flatArray));
I have data in this format. This is gamesparks data that is BaaS using for game development.
I am sending this data to the IOS person but he said he can not fetch this type of data so he told me to change the data
This is my actual data
{
"Details": [{
"5d4c2c28dcf224127a30457b": {
"displayName": "ewqeqw"
},
"5d4c4699dcf224127a3045e0": {
"displayName": "mmmmmmmmmm"
}
}]
}
and I need to change data in this format
{
"Details": [{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
},
{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
}
]
}
This is my code:
var group = Spark.getData().group;
var API = Spark.getGameDataService();
var all1 = new Array();
var entry = API.getItem("playerFriends", Spark.getPlayer().getPlayerId());
var friendsList = {};
if (entry.error()) {
Spark.setScriptError("ERROR", error);
Spark.exit();
} else {
var data = entry.document().getData();
if (group === "all") {
for (var friendOBJ in data) {
//Set details of player ID and display name in new friendsList
object
friendsList[friendOBJ] = {};
friendsList[friendOBJ].displayName = data[friendOBJ].displayName;
friendsList[friendOBJ].playerId = data[friendOBJ].playerId;
}
all1.push(friendsList);
} else {
for (var friendOBJ in data) {
if (data[friendOBJ].group === group && data[friendOBJ].status ===
"accepted") {
friendsList[friendOBJ] = {};
friendsList[friendOBJ].displayName = data[friendOBJ].displayName;
}
}
}
Spark.setScriptData("Details", all1);
Can you not just make a function to convert the data into the desired shape? Something like this should work:
function formatData(details) {
var formattedDetails = [];
for (var id in details) {
formattedDetails.push({
ID: id,
displayName: details[id].displayName
});
}
return formattedDetails;
}
var data = {
"Details": [
{
"5d4c2c28dcf224127a30457b": {
"displayName": "ewqeqw"
},
"5d4c4699dcf224127a3045e0": {
"displayName": "mmmmmmmmmm"
}
}
]
};
var formattedData = formatData(data.Details[0])
this is the output you want
{
"Details": [{
"ID": "5d499b0fdcf224127a303d61",
"displayName": "qweqewq"
}
}
and this is my code i am explaining each line with comment
var count = 0;
var tmp = { AcceptedFriendList: []}; //make object and inside empty array
for (var friendOBJ in data) { // retrieving data
if(data[friendOBJ].status === "accepted"){ // your condition
var tempObj = {"displayName" :"","playerid": ""}; //this is format you want
tempObj.displayName = data[friendOBJ].displayName; // putting data in spicify format object
tempObj.playerid = data[friendOBJ].ID;
tmp.AcceptedFriendList[count] = tempObj; //assign object back to array
count++; // iterate it so the next data come further.
}}
I want to create new array by json data But I have no idea to create Object!
for show to page(loop for)
my json data
"LIBRARIES":{
"LIBRARY":[
{
"status":"available",
"callNumber":"123456"
},
{
"status":"available",
"callNumber":"434356"
}
]
}
and
"search":{
"lsr02":[
"31011103618567",
"31011001644160"
]}
I want to create object to store this data
I want
"NEWDATA":{
"NEW":[
{
"status":"available",
"callNumber":"123456",
"lsr02": "31011103618567" ///set lsr02 to store in NEW
},
{
"status":"available",
"callNumber":"434356"
"lsr02":"31011001644160"
}
]
}
and I try
let details: string[] = [];
for (let x of this.item.LIBRARIES.LIBRARY){
details.push(x);
}
for (let x of this.item.search.lsr02){
details.push(x);
}
console.log(details)
console.log(details) show
{
"status":"available",
"callNumber":"123456"
},
{
"status":"available",
"callNumber":"434356"
}
{
"31011103618567"
},
{
"31011001644160"
}
thanks for your help :)
You are pushing the search objects separately. You need to assign them to appropriate library object. Try this;
this.item = {
"LIBRARIES": {
"LIBRARY": [{
"status": "available",
"callNumber": "123456"
},
{
"status": "available",
"callNumber": "434356"
}
]
},
"search": {
"lsr02": [
"31011103618567",
"31011001644160"
]
}
}
let details = [];
for (let i = 0; i < this.item.LIBRARIES.LIBRARY.length; i++) {
let lib = this.item.LIBRARIES.LIBRARY[i];
lib.lsr02 = this.item.search.lsr02[i]
details.push(lib);
}
console.log(details)
export class NEWDATA {
public status:string;
public callNumber:string;
public lsr02 : string;
constractor(_status : string, _callNumber : string, _lsr02 : string){
this.status = _status;
this.callNumber = _callNumber;
this.lsr02 = _lsr02;
}
}
details : Array<NEWDATA> = [];
for (let i = 0; i < this.item.LIBRARIES.LIBRARY.length; i++) {
details.push(new NEWDATA(this.item.LIBRARIES.LIBRARY[i].status, this.item.LIBRARIES.LIBRARY[i].callNumber, this.item.search.lsr02[i]));
}