How to convert json formatting from Object to Array - javascript

Another issue :P, I'm trying to change the output of the JSON array but I can't workout why it won't render the other files.
Edit better explanation below.
Sorry i was not very clear if you look at the code in my gist, data[name] = { will render all the return names into there individual json files, But if i remove the [name] and its just data = { the individual files are not rendered and the all.json file is made from the rendered [name] files.
Hope this explains it a little better.
The code you gave me dose add "markets" [] to the all.json file as it should but without the other files all.json only has one return.
The reason why i want to remove [name] from the data[name] = is that it adds the name to the start of the string of every return eg { "Bitcoin": {"position": "1", "name":"Bitcoin",},{"Litecoin": {"position":"2", "name": "Litecoin", }, and so on.
So i guess what i am trying to do is move the [name] from the data[name] =
into the fs.writeFile function and only add "markets": at the start of the string and still be able to render the individual files into all.json.
The Node.js code that will not render the individual files.
This versions all.json only returns
{"position":"650","name":"Pennies","symbol":"CENT","icon":"pennies.png","market_cap":{"usd":"NaN","btc":"?"},"price":{"usd":"2.26018e-9","btc":"9.05947e-12"},"supply":"","volume":{"usd":"43.9142","btc":"0.176021"},"change1h":"0.05","change24h":"3.77","change1d":"-7.07","timestamp":1435559515.397}
and in the json folder
http://s21.postimg.org/xm7v01ujr/image.jpg
What I would like is the JSON format to be:
{
"markets": [
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
},
{
"position": "2",
"name": "Litecoin",
and so on.......
}
]
}
#!/usr/bin/nodejs
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var currencies = ["usd", "btc"];
var currencyExchangeRates = Array();
var data = {};
request('http://coinmarketcap.com/all/views/all/', function (error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
currencyExchangeRates = $("#currency-exchange-rates").data();
$("tr").each(function (i) {
if (i > 0) {
var td = $(this).find("td");
var position = td.eq(0).text().trim();
var icon = $(this).find("img.currency-logo").attr("src").replace("/static/img/coins/16x16/", "");
var name = td.eq(1).text().replace("/", "").trim();
var re = /\s([a-z]|[0-9])+\s/i;
var supplyText = td.eq(5).text();
var symbol = td.eq(2).text().trim();
var marketCap = currencyDictionary(td.eq(3));
var price = currencyDictionary(td.eq(4).find("a").eq(0));
var supply = td.eq(5).text().replace(/\D/g, "").trim(); // Replace all non digit characters with nothing
var volume = currencyDictionary(td.eq(6).find("a").eq(0));
var change1h = td.eq(7).text().replace("%", "").trim();
var change24h = td.eq(8).text().replace("%", "").trim();
var change1d = td.eq(9).text().replace("%", "").trim();
var timestamp = Date.now() / 1000;
data = [{
"position": position,
"name": name,
"symbol": symbol,
"icon": icon,
"market_cap": marketCap,
"price": price,
"supply": supply,
"volume": volume,
"change1h": change1h,
"change24h": change24h,
"change1d": change1d,
"timestamp": timestamp
}];
}
});
writeData();
}
});
function currencyDictionary(item) {
var resultArray = {};
currencies.forEach(function(currency) {
if (currency == "btc") {
var result = item.data("btc");
}
else {
var result = item.data("usd") / currencyExchangeRates[currency];
}
resultArray[currency] = result.toString().replace(/,/g,"");
});
return resultArray;
}
function writeData() {
dataDir = "/var/www/coinmarketcap/json/";
callback = function(error) {
if (error) {
console.log(error);
}
};
for (currency in data) {
info = data[currency];
fileName = dataDir + info["symbol"] + ".json";
fs.writeFile(fileName, JSON.stringify(info), callback);
}
fs.writeFile(dataDir + "all.json", JSON.stringify(data), callback);
}
This version will render all the files but adds the [name] to the all.json
this version json folder
http://s16.postimg.org/xicupqi85/image.jpg
The JSON format is:
{
"Bitcoin":
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
},
{
"Litecoin":
{
"position" "2",
"name": "Bitcoin",
and so on...
}
}
#!/usr/bin/nodejs
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var currencies = ["usd", "btc"];
var currencyExchangeRates = Array();
var data = {};
request('http://coinmarketcap.com/all/views/all/', function (error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
currencyExchangeRates = $("#currency-exchange-rates").data();
$("tr").each(function (i) {
if (i > 0) {
var td = $(this).find("td");
var position = td.eq(0).text().trim();
var icon = $(this).find("img.currency-logo").attr("src").replace("/static/img/coins/16x16/", "");
var name = td.eq(1).text().replace("/", "").trim();
var re = /\s([a-z]|[0-9])+\s/i;
var supplyText = td.eq(5).text();
var symbol = td.eq(2).text().trim();
var marketCap = currencyDictionary(td.eq(3));
var price = currencyDictionary(td.eq(4).find("a").eq(0));
var supply = td.eq(5).text().replace(/\D/g, "").trim(); // Replace all non digit characters with nothing
var volume = currencyDictionary(td.eq(6).find("a").eq(0));
var change1h = td.eq(7).text().replace("%", "").trim();
var change24h = td.eq(8).text().replace("%", "").trim();
var change1d = td.eq(9).text().replace("%", "").trim();
var timestamp = Date.now() / 1000;
data[name] = {
"position": position,
"name": name,
"symbol": symbol,
"icon": icon,
"market_cap": marketCap,
"price": price,
"supply": supply,
"volume": volume,
"change1h": change1h,
"change24h": change24h,
"change1d": change1d,
"timestamp": timestamp
};
}
});
writeData();
}
});
function currencyDictionary(item) {
var resultArray = {};
currencies.forEach(function(currency) {
if (currency == "btc") {
var result = item.data("btc");
}
else {
var result = item.data("usd") / currencyExchangeRates[currency];
}
resultArray[currency] = result.toString().replace(/,/g,"");
});
return resultArray;
}
function writeData() {
dataDir = "/var/www/coinmarketcap/json/";
callback = function(error) {
if (error) {
console.log(error);
}
};
for (currency in data) {
info = data[currency];
fileName = dataDir + info["symbol"] + ".json";
fs.writeFile(fileName, JSON.stringify(info), callback);
}
fs.writeFile(dataDir + "all.json", JSON.stringify(data), callback);
}

Try utilizing for...in loop
var data = {
"Bitcoin":
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
}
};
var res = {"markets":[]};
for (var prop in data) {
res.markets.push(data[prop])
};
document.getElementsByTagName("pre")[0].textContent = JSON.stringify(res, null, 4);
<pre></pre>

Worked it out, had to move the fs.writeFile for all.json out of the writeData function and give all.json its own function that is called after the writeData function had finished.

Related

Looping through items in an object for google sheets

I am trying to loop through an array that is part of a JSON object from a page speed insights call to add all of the unused javascript Urls to a google sheet using the script editor.
Here is an example of the JSON object:
"audits": {
"unused-javascript": {
"id": "unused-javascript",
"title": "Remove unused JavaScript",
"description": "Remove unused JavaScript to reduce bytes consumed by network activity. [Learn more](https://web.dev/unused-javascript/).",
"score": 0.43,
"scoreDisplayMode": "numeric",
"numericValue": 1350,
"numericUnit": "millisecond",
"displayValue": "Potential savings of 231 KiB",
"details": {
"type": "opportunity",
"headings": [
{
"key": "url",
"valueType": "url",
"subItemsHeading": {
"key": "source",
"valueType": "code"
},
"label": "URL"
},
{
"key": "totalBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceBytes"
},
"label": "Transfer Size"
},
{
"key": "wastedBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceWastedBytes"
},
"label": "Potential Savings"
}
],
"items": [
{
"url": "https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable",
"totalBytes": 140229,
"wastedBytes": 108197,
"wastedPercent": 77.15757011763822
},
{
"url": "https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js",
"totalBytes": 306716,
"wastedBytes": 106243,
"wastedPercent": 34.63892414884589
},
{
"url": "https://www.googletagmanager.com/gtm.js?id=GTM-KZ",
"totalBytes": 127214,
"wastedBytes": 21845,
"wastedPercent": 17.17151000374831
}
],
"overallSavingsMs": 1350,
"overallSavingsBytes": 236285
}
},
I am attempting to loop through the "items" array within the "unused-javascript" object and get all of the urls to show in google sheets.
Here is the code I have within the script editor. When I run this, only one URL shows on the sheet. However, I am trying to get all of the URLs added to the sheet.
function pageSpeed(Url) {
var key = "AIzaSyAyHY";
var serviceUrl = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + Url + "&key=" + key;
var array = [];
if (key == "YOUR_API_KEY")
return "Please enter your API key to the script";
var response = UrlFetchApp.fetch(serviceUrl);
if (response.getResponseCode() == 200) {
var content = JSON.parse(response.getContentText());
if ((content != null) && (content["lighthouseResult"] != null)) {
if (content["captchaResult"]) {
var timetointeractive = content["lighthouseResult"]["audits"]["interactive"]["displayValue"].slice(0, -2);
var firstcontentfulpaint = content["lighthouseResult"]["audits"]["first-contentful-paint"]["displayValue"].slice(0, -2);
var firstmeaningfulpaint = content["lighthouseResult"]["audits"]["first-meaningful-paint"]["displayValue"].slice(0, -2);
var speedindex = content["lighthouseResult"]["audits"]["speed-index"]["displayValue"].slice(0, -2);
var unusedJs = content["lighthouseResult"]["audits"]["unused-javascript"]["details"]["items"];
for (var i = 0; i < unusedJs.items.length; i++) {
var unusedUrl;
unusedUrl = unusedJs[i]["url"]
}
}
else {
var timetointeractive = "An error occured";
var firstcontentfulpaint = "An error occured";
var firstmeaningfulpaint = "An error occured";
var speedindex = "An error occured";
var unusedJs = "An error occured";
}
}
var currentDate = new Date().toJSON().slice(0, 10).replace(/-/g, '/');
array.push([timetointeractive, firstcontentfulpaint, firstmeaningfulpaint, speedindex, currentDate, "complete", unusedUrl]);
Utilities.sleep(1000);
return array;
}
}
Any and all help is appreciated!
You're on the right track.
Take a look below at my usage of Array.prototype.map. That's the simpler route.
Your for loop would work just as well IF you declared unusedUrl outside of (ie. before) the loop AND pushed to an existing array. As it is, there's an issue of scope, so unusedUrl is redeclared on every iteration, meaning you'll only assign the last iteration's value to unusedUrl.
Both solutions are below.
Using map
var content = {
lighthouseResult: {
audits: {
'unused-javascript': {
// Other stuff
details: {
// Other stuff
items: [
{
url:
'https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable',
totalBytes: 140229,
wastedBytes: 108197,
wastedPercent: 77.15757011763822,
},
{
url:
'https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js',
totalBytes: 306716,
wastedBytes: 106243,
wastedPercent: 34.63892414884589,
},
{
url: 'https://www.googletagmanager.com/gtm.js?id=GTM-KZ',
totalBytes: 127214,
wastedBytes: 21845,
wastedPercent: 17.17151000374831,
},
],
overallSavingsMs: 1350,
overallSavingsBytes: 236285,
},
},
},
},
}
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = items.map(item => item.url) // OR, using es6, items.map(({ url }) => url)
console.log(unusedUrls)
Using for
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = []
for (var i = 0; i < items.length; i++) {
unusedUrls.push(items[i]['url'])
}

recursion with Promises

I have a collection in MongoDB like this
[
{
"classId": "1",
"name": "Input",
"definition": [
{
"property": [
{
"classId": "12",
"name": "One"
},
{
"classId": "8",
"name": "Comment"
}
]
}
]
},
{
"classId": "8",
"name": "CommentDetail",
"definition": [
{
"property": [
{
"classId": "10",
"name": "user"
},
{
"classId": "10",
"name": "message"
}
]
}
]
},
{
"classId": "10",
"name": "String",
"definition": []
},
{
"classId": "12",
"name": "Int",
"definition": []
}
]
Based on db above, I have a model to display
data = {
name:'',
template: ''
}
With classId=1, the expectation result is
{
"Name": "Input",
"temlate": "{['One': 'Int','Comment': ['user': 'String','message':'String']]}"
}
I try to using recursive promise to implement it. When property[] is empty, the result will be return.
Here is my function:
const getObjectTypeByClassId = (snapshotId, artifactId, objectType) => {
return artifactDetailModel.find({
'snapshotId': snapshotId,
'artifactId': artifactId
})
.then(data => {
let artifact = data[0];
let definition;
let definitionData = {};
return Promise.resolve()
.then(() => {
definition = artifact.data.teamworks.twClass[0].definition[0];
if (!lodash.isUndefined(definition.property)) {
const listOfProperty = definition.property;
for (let property of listOfProperty) {
classId = commonUtil.getArtifactId(property.classRef[0]);
if (!lodash.isUndefined(classId)) {
return getObjectTypeByClassId(snapshotId, classId, objectType);
}
}
} else {
definitionData.nameType = artifact.data.teamworks.twClass[0].elementAttribute.name;
definitionData.classId = artifact.data.teamworks.twClass[0].elementAttribute.id;
definitionData.template = bpmMapping.objectType[artifact.data.teamworks.twClass[0].elementAttribute.name];
return objectTypeModel.create(definitionData)
.then(obj => {
const response = {
name: objectType.name,
isArrayOf: objectType.isArrayOf,
nameType: obj.nameType,
template: obj.template,
}
return response;
})
}
})
})
}
Run with my function, the response is
data: {
Name: Input
temlate: user: String,
}
Please advice me.
I tried it to some extent, but wasn't able to get it right. Plus your expected output is not the valid JSON "temlate": {[]} doesn't make sense.
It has nothing to do with Promise. You have to DFS you db array and created expected output. Here is what I have donup tillll now, you can think along those lines. But this is far from the solution.
let mainArray = [
{
"classId": "1",
"name": "Input",
"definition": [
{
"property": [
{
"classId": "12",
"name": "One"
},
{
"classId": "8",
"name": "Comment"
}
]
}
]
},
{
"classId": "8",
"name": "CommentDetail",
"definition": [
{
"property": [
{
"classId": "10",
"name": "user"
},
{
"classId": "10",
"name": "message"
}
]
}
]
},
{
"classId": "10",
"name": "String",
"definition": []
},
{
"classId": "12",
"name": "Int",
"definition": []
}
]
function dfs(root, createdRoot, fn, level) {
fn(root,createdRoot, level);
if(root.definition)/*if definition exists => keep traversing*/
root.definition[0].property.forEach(function (child) {
createdRoot.template = createdRoot.template || [];
let tempObj = {};
let lookupObj = lookupByClassId(child.classId);
tempObj[child.name] = lookupObj.name;
createdRoot.template.push(tempObj);
dfs(child,tempObj, fn, level + 1);
});
else /*if definition doesn't exist, look into the array*/
{
createdRoot.template = lookupByClassId(root.classId);
}
}
function lookupByClassId(classId){
for(let i=0;i<mainArray.length;++i){
let element =mainArray[i]
if(element.classId == classId)
return element;
}
}
let root = lookupByClassId(1);
createdRoot ={};
function func1(root, createdRoot, level) {
createdRoot.name = root.name;
console.log(root.classId);
}
dfs(root, createdRoot, func1, 0);
here is the solution from a guy on the internet. it works well. Thanks, #Cuong Quach
var MongoClient = require('mongodb').MongoClient;
var database = 'testdequy';
var collection = 'classes';
MongoClient.connect("mongodb://localhost:27017/" + database, function (err, db) {
findDetails("1").then((r) => {
console.log("r>>>", r);
})
function findDetails(classId) {
var results = { Name: "", Template: "" };
var template = {};
return new Promise((main_resolve, reject) => {
process(template, "" , classId)
var works = 0;
function process(parent, childKey, objectId) {
return new Promise((resolve, reject) => {
db.collection(collection).find({ classId: objectId })
.toArray((err, docs) => {
if (results.Name == "") {
results.Name = docs[0].name;
}
let objectItem;
if (childKey == "")
objectItem = parent;
else
objectItem = parent[childKey];
console.log("\ndocs", docs[0], objectId, objectItem)
if (docs[0].definition.length == 0 || docs[0].definition[0].property == undefined) {
let name = docs[0].name;
parent[childKey] = name;
console.log("\nNo child", docs[0],parent, objectItem, docs[0].name)
resolve(0);
} else {
docs[0].definition[0].property.forEach((item) => {
works++;
//console.log("item", item)
let id = item.classId;
let name = item.name;
objectItem[name] = {};
process(objectItem, name, id).then((len)=>{
works--;
if(len == 0 && works == 0) main_resolve(template);
})
})
resolve(docs[0].definition[0].property.length)
}
})
})
}
})
}
});

print full path javascript

This is the result I am getting from my database when I do a query:
[
{
"name": "file1.txt",
"id": 1,
"file_path": "./public/files/file1.txt"
}
{
"name": "file3.txt",
"id": 3,
"file_path": "./public/files/file3.txt"
},
{
"name": "file4.txt",
"id": 8,
"file_path": "./public/files/file4.txt"
},
{
"name": "file5.txt",
"id": 7,
"file_path": "./public/files/file5.txt"
}
]
And what I want to print is this kinda of format of file path ./public/files/file1.txt
This is what I am trying right now but it doesn't seem to work:
var paths = [];
if(result.length > 0) {
var tmp_path = result[0].file_path
var count = 0
result.forEach(element => {
count++
tmp_path = element.file_path
paths.push(decodeURI(tmp_path))
})
console.log(JSON.stringify(paths,null,4))
}
The result I get is this:
[
"./public/files/file1.txt",
"./public/files/file3.txt",
"./public/files/file4.txt",
"./public/files/file5.txt",
]
Isn't decodeURI() the function I am supposed to use in this case?
I am working on Node.js with router and ejs npms. So this is part of a get function and the result will be populated in front-end with ejs. So what I am trying to do is to pass the correct format on the result which is PATHS
You can tweak your code so that that file path is saved as a HTML content in a element say, div then get the HTML from this element to get the decoded value and push it into the array.
var result = [
{
"name": "1k",
"id": 1,
"file_path": "./public/files/file1.txt"
},
{
"name": "3k",
"id": 3,
"file_path": "./public/files/file3.txt"
},
{
"name": "4k",
"id": 8,
"file_path": "./public/files/file4.txt"
},
{
"name": "5k",
"id": 7,
"file_path": "./public/files/file5.txt"
}
];
var paths = [];
if(result.length > 0) {
var tmp_path = result[0].file_path
var count = 0
result.forEach(element => {
count++;
tmp_path = element.file_path;
var elem = document.createElement('div');
elem.innerHTML = tmp_path;
paths.push(elem.innerHTML);
})
console.log(JSON.stringify(paths,null,4))
}
Not sure if this would work for you, but you can use a .map to remap the array into an array of strings making slight adjustments:
So for each file_path split with ';' then take the last element of the split 'filei.text' and concatenate './public/files/' before it.
const res = data.map(e => {
const path = e.file_path.split(';');
const fileName = path[path.length-1];
return './public/files/' + fileName;
});
const data = [
{
"name": "1k",
"id": 1,
"file_path": "./public/files/file1.txt"
},
{
"name": "3k",
"id": 3,
"file_path": "./public/files/file3.txt"
},
{
"name": "4k",
"id": 8,
"file_path": "./public/files/file4.txt"
},
{
"name": "5k",
"id": 7,
"file_path": "./public/files/file5.txt"
}
];
const res = data.map(e => {
const path = e.file_path.split(';');
const fileName = path[path.length-1];
return './public/files/' + fileName;
});
console.log(res)
You can use decodeURI() in the following way
var uri = "./public/files/file1.txt";
var enc = encodeURI(uri);
var dec = decodeURI(enc);
You can show this URL in html like below:
document.getElementById("demo").innerHTML = dec;
just encode the file_path with encodeURI you will get original url
e.g.:
var uri = "./public/files/file1.txt";
console.log(encodeURI(uri));
Will return:
"./public/files/file1.txt"

option selects from json object on categories

Hi (sorry for my english), I have this script:
<script type="text/javascript">
$(document).ready(function() {
var idPlato = decodeURI(getUrlVars()["idPl"]);
var url = "http://localhost/plato-datos.php?idPla="+idPlato+"";
});
};
</script>
It brings me this json from my database:
[{"category":"first","name":"green","idP":"1", "count":3},
{"category":"first","name":"blue","idP":"2","count":5},
{"category":"sec","name":"peter","idP":"3", "count":3},
{"category":"sec","name":"james","idP":"4", "count":2,},
{"category":"third","name":"dog","idP":"5", "count":4}]
I need to create one radiobuton for every name and group by categores
I create a solution. Kinda ugly but it will work:
var data = [{
"category": "first",
"name": "green",
"idP": "1",
"count": 3
}, {
"category": "first",
"name": "blue",
"idP": "2",
"count": 5
}, {
"category": "sec",
"name": "peter",
"idP": "3",
"count": 3
}, {
"category": "sec",
"name": "james",
"idP": "4",
"count": 2,
}, {
"category": "third",
"name": "dog",
"idP": "5",
"count": 4
}];
var result = {};
data.map(a => {
if (result[a.category]) {
result[a.category].push(a.name);
} else {
result[a.category] = [a.name];
}
});
Object.keys(result).map(category => {
var select = document.createElement('select');
result[category].map(name => {
var option = document.createElement('option');
option.value = name;
option.text = name;
select.appendChild(option);
});
document.body.appendChild(select);
});
Im working with jquery mobile then i used autodividersSelector function for group by the category JSON object, and build a radiobuton for every name
<script type="text/javascript">
//catch the JSON from my database
$(document).ready(function() {
var idPla = decodeURI(getUrlVars()["idPl"]);
var urlAder =
"http://localhost/lista-adereso.php?idPla=" + idPla + "";
//print the radiobutons
$.getJSON(urlAder, function(resultado) {
var allfiles = '';
for (var i = 0, aderesos = null; i <
resultado.length; i++) {
aderesos = resultado[i];
allfiles +='<li><label><input type="radio" data-
status="' + aderesos.aderesoCatNom +'"
name="name" id="id" value="' +
aderesos.aderNombre +'">'+
aderesos.aderNombre + '</label></li>'; }
//Group by categories
$('#linkList')
.empty()
.append(allfiles)
.listview({
autodividers:true,
autodividersSelector: function ( li ) {
var out = li.find('input').data("status");
return out;
}
})
.listview("refresh");
});
});
</script>

Create Hashmap like implementation using java-script for json

I am looking to create hashmap like array which will contain key and value derived from another array which has nested objects.
so i am trying the following code.
var testhash={},data=[
{
"yang_type": "container",
"name": "c1",
"value": "",
"children": [
{
"yang_type": "container",
"name": "c2",
"value": "",
"children": [
{
"yang_type": "list",
"name": "Car",
"value": "",
"children": [
{
"yang_type": "leaf",
"name": "wheels",
"value": "",
"children": [
{
"name": "max-elements",
"value": "4",
"children": [],
"yang_type": ""
}
]
}
]
},
{
"yang_type": "",
"name": "text",
"value": "4",
"children": []
}
]
}
]
}
];
var k='';
function loop1(a, depth) {
var l,s='';
if(depth){s += '/';}
k=k+a.yang_type+a.name+a.value;
v=Array(depth + 1).join(s) + a.yang_type+a.name+a.value;
testhash.push(k:v);
//console.log(l);
//console.log(Array(depth + 1).join("/") + a.yang_type,a.name,a.value);
//hashServiceParams.push(Array(depth + 1).join("/") + a.yang_type,a.name,a.value);
Array.isArray(a.children) && a.children.forEach(function(child) {
loop1(child, depth + 1);
});
}
console.log(testhash);
The output, I am expecting is
{"containerc1":*,"containerc2":"containerc1/containerc2","listcar":"containerc1/containerc2/listcar","leafwheels":"containerc1/containerc2/listcar/leafwheels","max-elements":"containerc1/containerc2/listcar/leafwheels/max-elements","text4":"containerc1/text4"}
The above array will act as an hash map that contains key and value , where value stores the part of that data in the tree structure.
my code just calculates the depth and adds / to each level it moves down but i expect the output to be as shown above. Any recommendation coders ?
The following should do the trick (use either version according to your needs):
ECMAScript 6:
function parseData(data, prefix) {
let result = {};
data.forEach(o => {
const key = `${o.yang_type}${o.name}`;
result[key] = prefix ? `${prefix}/${key}` : '*';
if (o.children) {
const newPrefix = prefix ? `${prefix}/${key}` : key;
result = Object.assign(result, parseData(o.children, newPrefix));
}
});
return result;
}
ECMAScript 5:
function shallowMerge(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
function parseData(data, prefix) {
var result = {};
data.forEach(function (o) {
var key = '' + o.yang_type + o.name;
result[key] = prefix ? prefix + '/' + key : '*';
if (o.children) {
var newPrefix = prefix ? prefix + '/' + key : key;
result = shallowMerge(result, parseData(o.children, newPrefix));
}
});
return result;
}
In order to use it you simply need to do the following:
let testhash = parseData(data);
This will populate the testHash with the result you need.

Categories

Resources