Hello dear stackoverflow community,
I want to make an Electron app [Javascript not jQuary] (or am in the process of doing so) and would like to add a function that puts one config into the "format" of another.
The big file from which I want to take the information I currently read in via "dialog.showOpenDialog" and can also access the json object.
Now to the problem:
The file I get via the dialog is 8000 lines long and contains individual information that I want to pack into a smaller document with about 3000 lines. Important: Individual information have a different name e.g. I want "ABCD: 23" from document 1 in the other as EFG: 23.
I had already asked this question and also received a good answer from a user[click here] which also works well, however I have now copied and pasted the function several times (as below in the example with the for function)
And this is of course not the fine English way... is there a way to make this more compact?
BigCFG.json:
"ANIMALS"{
"DOG": {
"DOG1": "0" ,
"DOG2": "1" ,
"BREED": {
"breed": "1",
"breed": "2",
},
},
"CAT": {
"CAT1": "0",
"CAT2": "1" ,
"BREED": {
"breed": "1",
"breed": "2",
},
},
}
Tables:
let dogTable = {
'dog1':'dog2',
'dog3': 'dog4'
}
let dogbreedTable = {
'breed1':'breed2',
'breed3': 'breed4'
}
let catTable = {
'cat1':'cat2',
'cat3': 'cat4'
}
let catbreedTable = {
'breed1':'breed2',
'breed3': 'breed4'
}
The for function which I would like to have more compact: (I have the currently about 40 times in my project in a row to test)
for (let bigKey in BigCFG.ANIMALS.DOG) {
if (bigKey in dogTable) {
smallCFG.ANIMALS.DOG[dogTable[bigKey]] = BigCFG.ANIMALS.DOG[bigKey]
}
for (let bigKey in BigCFG.ANIMALS.DOG.BREED) {
if (bigKey in dogbreedTable) {
smallCFG.ANIMALS.DOG.BREED[dogbreedTable[bigKey]] = BigCFG.ANIMALS.DOG.BREED[bigKey]
}
for (let bigKey in BigCFG.CAT) {
if (bigKey in catTable) {
smallCFG.ANIMALS.CAT[catTable[bigKey]] = BigCFG.ANIMALS.CAT[bigKey]
}
for (let bigKey in BigCFG.ANIMALS.CAT.BREED) {
if (bigKey in catbreedTable) {
smallCFG.ANIMALS.CAT.BREED[catbreedTable[bigKey]] = BigCFG.ANIMALS.CAT.BREED[bigKey]
}
Expected smallCFG.json:
"ANIMALS": {
"CAT": {
"cat": "3",
"cat": "4",
"BREED": {
"breed": "2",
"breed": "3",
},
},
"DOG": {
"dog": "3",
"dog": "4",
"BREED": {
"breed": "3",
"breed": "4",
},
}
}
I would be very grateful for the help and of course appreciate your time
Not sure if I fully understood your problem and constraints. What I get by your other questions is you need to transform a json document for one structure to another, right? Have you tried JSONata? Maybe it matches your requirements.
PS.: I've tried add this as a comment, but I don't have reputation enough
Related
I am trying to read JSON response data from a Restful API that contains a space in the path. I am trying to accomplish this in JavaScript, but can't seem to get the data to display.
Below is the JSON I am working with:
"fields": {
"census": {...},
"acs": {
"meta": {
"source": "American Community Survey from the US Census Bureau",
"survey_years": "2014-2018",
"survey_duration_years": "5"
},
"demographics": {
"Median age": {
"meta": {
"table_id": "B01002",
"universe": "Total population"
},
"Total": {
"value": 32.8,
"margin_of_error": 0.6
As you can see, the Median Age field has a space. The actual data I am trying to obtain is the Median age total value.
Below is my JSON path that isn't working:
let ageDems = await response.data.results[0].fields.demographics.$["Median age"].Total.value;
I have also tried to use ['Median Age'], ["Median Age"] and Median+Age and none of those worked either.
Can anyone please assist me in writing the correct path to obtain the data I need?
await response.data.results[0].fields.demographics["Median age"].Total.value;
Ismail's suggestion does work.
This answer is here just to prove it to you. If this is not working for you as demonstrated below, please provide a Minimal, Reproducible Example that shows the error you see.
const data = {
"acs": {
"meta": {
"source": "American Community Survey from the US Census Bureau",
"survey_years": "2014-2018",
"survey_duration_years": "5"
},
"demographics": {
"Median age": {
"meta": {
"table_id": "B01002",
"universe": "Total population"
},
"Total": {
"value": 32.8,
"margin_of_error": 0.6
}
}
}
}
};
console.log(data.acs.demographics["Median age"].Total.value);
demographics is nested under acs:
await response.data.results[0].fields.acs.demographics["Median age"].Total.value
I have several objects like this and wonder how I can search between these, say that we got the number 1 and want to figure out what the name is.
Should I loop it or what do you guys suggest?
To make things clear, I do want to get the other objects by using the number. Is it possible?
{
"room": [
{
"number": "1",
"name": "room1"
},
{
"number": "2",
"name": "room2"
}
]
}
You could use a map and use the room number as identifier. This way you can access the room data via the room number like that:
var data = {
"room": [
{
"number": "1",
"name": "room1"
},
{
"number": "2",
"name": "room2"
}
]
};
// or load it from a file:
// var data = require('./data.json');
var rooms = new Map();
for(room of data.room) {
rooms.set(Number(room.number), room);
}
// access data for room with number 1
alert(rooms.get(1).name);
Firstly, bring in the file. Make sure to include the './' before the file name to show that it's from the current directory.
const data = require('./data.json');
Now the JSON data is stored inside the variable data. To access the members, use the dot operator. data.room will return the array of rooms.
To access the individual room, use data.room[i] where i is the numbered element in the array (starting from 0). For example, to access the first room:
const first_room = data.room[0];
This first_room variable can now be used to access the name.
console.log(first_room.name);
This will log "room1" to the console.
You can try this. This will help you.
var roomData = {
"room": [
{
"number": "1",
"name": "room1"
},
{
"number": "2",
"name": "room2"
}
]
}
for(key in roomData.room){
console.log("Room Number - " + roomData.room[key].number);
console.log("Room Name - " + roomData.room[key].name);
}
Upon viewing the Mongo Count docs, it showed the following code :
// Peform a partial account where b=1
collection.count({b:1}, function(err, count) {
where it count every document that has b:1. Those documents can look something like this
{
a:1,
b:1,
c:1
}
How can I find the partial account on a more in-depth level. For example consider the following document. How can I count every document that contains
"Name": "LOG-11-05-SH-O1.mp4" ?
"display": {
"0": {
"Name": "LOG-11-05-SH-O1.mp4",
"Type": "Startup",
"Count": "2",
"Detail": {
"0": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
},
"1": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
}
}
},
"1": { ....
I know that "display.0.Name" : "LOG-11-05-SH-O1.mp4" will count everytime "LOG-11-05-SH-O1.mp4" appears under display 0, but sometimes the number may change. For example, next time time "LOG-11-05-SH-O1.mp4" might be under display 1. Thus is there a way to perform a count on only "LOG-11-05-SH-O1.mp4" or perhaps ignore the middle number?
See my comments on your question, but I don't see a way to do this without using an array instead of an object for the value of display. If it is an array, this becomes trivial.
Suppose your data looked like this:
"display": {[
{
"Name": "LOG-11-05-SH-O1.mp4",
"Type": "Startup",
"Count": "2",
"Detail": {
"0": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
},
"1": {
"Start": "2013-01-20,11:32:22",
"End": "2013-01-20,11:32:30"
}
}
, { ....}
]}
Then you query would just be:
db.foos.count({"display": {$elemMatch: { "Name" : "LOG-11-05-SH-O1.mp4"}}})
Here is the relevant MongoDB page on $elemMatch: http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/.
If you must keep the object schema, then you can grab all the records and do the count on the app side and not in MongoDB.
If someone else knows a way to pull this off without the array, I'm happy to receive a downvote and then just remove what would then be an incorrect answer.
I feel kind of silly not realizing this at first. The answer is quite simple:
"display.Name": "LOG-11-05-SH-O1.mp4"
This will find all entries under display that has that following name.
I'm having trouble finding a solution that will help me loop through a bunch of elements and putting the chosen values into a table. I've been able to withdraw some values but the method isn't dynamic.
Here is an example:
var Table = {
"credit": {
"link": "site link",
"logoUrl": "logo url",
"message": "message"
},
"groups": [
{
"labels": [
{
"name": "Western Conference",
"type": "conference"
},
{
"name": "Central Division",
"type": "division"
}
],
"standings": [
{
"stats": [
{
"name": "gp",
"value": 20
},
{
"name": "w",
"value": 17
},
{
"name": "l",
"value": 0
},
{
"name": "gf",
"value": 64
},
{
"name": "ga",
"value": 37
},
{
"name": "gd",
"value": 27
},
{
"name": "pts",
"value": 37
}
],
"team": {
"id": 12345,
"link": "team link",
"name": "team name",
"shortName": "team"
}
},
This is the structure of the elements. So far I've used this:
document.getElementById("sGamesPlayed").innerHTML=Table.groups[0].standings[0].stats[0].value;
to withdraw values. However there are more teams, stats and divisions so I would need some kind of loop to go through the elements and put the into a dynamic table.
I would consider you to look at http://underscorejs.org/.
it provides a bunch of utility functions that could help you,
for example, _.each() helps you loop through JSON properties.
for the sample objects you've given (after completing the missing brackets at the end),
_.each(Table.groups[0].standings[0].stats, function(stats){
console.log(stats['name']+","+stats['value'])
})
gives me:
gp,20
w,17
l,0
gf,64
ga,37
gd,27
pts,37
how it works is that you provide the object you want as the first argument and the function that you give as the second argument will be called with each element of the first argument (Assuming it is a list).
I would also urge you to look at underscore templating that you can use to render your table where i put the console.log :
http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/
http://scriptble.com/2011/01/28/underscore-js-templates/
I guess your question is about filtering the values of the array standings. In order to do that you can use the jQuery grep function (if you want to use jQuery).
For example you can write:
var arr = $.grep(Table.groups[0].standings[0].stats, function(d){return d.value>25})
Which will give
arr = [{"name": "gf","value": 64}, {"name": "ga", "value": 37},{"name": "gd", "value": 27},{"name": "pts", "value": 37}]
If this is not what you meant, can you please create a jsFiddle with a sample of what you want?
Depending on what you want to do with the results, you can go over the object using a scheme like:
var groups, standings, stats, value;
groups = Table.groups;
// Do stuff with groups
for (var i=0, iLen=groups.length; i<iLen; i++) {
standings = groups[i].standings;
// Do stuff with standings
for (var j=0, jLen=standings.length; j<jLen; j++) {
stats = standings[j];
// Do stuff with stats
for (var k=0, kLen=stats.length; k<kLen; k++) {
value = stats[k].value;
// Do stuff with value
}
}
}
Of course I have no idea what the data is for, what the overall structure is or how you want to present it. But if you have deeply nested data, all you can do is dig into it. You might be able to write a recursive function, but it might also become very difficult to maintain if the data structure is complex.
I wrote the following JavaScript function (part of a larger "class") to help ensure anybody using the object stores attribute values in the "values" property.
function _updateAttributes(attribute, value) {
_attributes[attribute] = { values: { value: value }};
}
It works fine for a flat structure, but falls apart when I start trying to use it for sub-properties.
After running the following code:
myEntity.updateAttribute('name', 'Frankenstein');
myEntity.updateAttribute('name.source', 'John Doe');
I'd like the following structure:
{
"attributes": {
"name": {
"values": {
"value": "Frankenstein"
},
"source": {
"values": {
"value": "JohnDoe"
}
}
}
}
}
Instead, it's coming out like this:
{
"attributes": {
"name": {
"values": {
"value": "Frankenstein"
}
},
"name.source": {
"values": {
"value": "JohnDoe"
}
}
}
}
Is there any clean way to write this JavaScript or will I be faced with splitting out the strings and manually building the structure?
NOTE: I realize even the preferred structure is a little odd, but there's a Java object I'm mapping to that expects this format, so I don't have any options here.
You'll have to parse the string (parse is a bit strong, just a single split('.') with a loop).
But frankly, the cleaner way would simply be:
myEntity.name = {values: 'Frankenstein'};
myEntity.name.source = {values: 'John Doe'};