I have an odd requirement to prettify a JSON structure in a very precise way. Currently I'm using angular.toJson(jsonObj, true) to auto-prettify it.
However, how could I do customized formatting. Given the following JSON:
{"SomeArray": [
{
"Description": "Some sort of description",
"a": 0,
"b": "foo0",
"c": "bar0"
},
{
"a": 0,
"b": "foo1",
"c": "bar1",
"d": "DoSomething1"
},
{
"a": 0,
"b": "foo2",
"c": "bar2",
"d": "DoSomething2"
},
{
"Description": "Another description",
"a": 0,
"b": "foo3",
"c": "bar3",
"d": "DoSomething3"
},
{
"a": 0,
"b": "foo4",
"c": "bar4",
"d": "DoSomething4"
}]}
How can I format this to look exactly like the following? Basically I need to keep "description" keys on it's own seperate line, while the other keys are on a line immediately below it, as well as keeping the curly brace on the same line as well:
{"SomeArray": [
{ "Description": "Some sort of description",
"a": 0, "b": "foo0", "c": "bar0" },
{ "a": 0, "b": "foo1", "c": "bar1", "d": "DoSomething1" },
{ "a": 0, "b": "foo2", "c": "bar2", "d": "DoSomething2" },
{ "Description": "Another description",
"a": 0, "b": "foo3", "c": "bar3", "d": "DoSomething3" },
{ "a": 0, "b": "foo4", "c": "bar4", "d": "DoSomething4" }]}
Figured I'd circle back around and answer how I wound up solving this. Just wound up using HandleBars.js. It's a pretty slick templating engine. I wrote the template of how I want json output to look, then just passed it the object I wanted formatted. The net results was formatting exactly as I needed it, with very little effort!
If anyone else is struggling with formatting JSOn for whatever reason, I strongly recommend checking out Handlebars.
Related
How can I select certain values and/or values conditional on other columns in vega-lite? For example, below I only want to show values that have "red" in the column "c".
{
"data": {
"values": [
{"a": "A", "b": 2, "c": "red"},
{"a": "A", "b": 7, "c": "red"},
{"a": "A", "b": 4, "c": "blue"},
{"a": "B", "b": 1, "c": "blue"},
{"a": "B", "b": 2, "c": "red"}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "nominal"},
"y": {"aggregate": "average", "field": "b", "type": "quantitative"}
}
}
I have tried adding the following code before "mark": "bar", according to this vega github tutorial, and using the online vega editor, but it doesn't filter column b. I thought I could use it to somehow filter a string as well.
"transform": {
"filter": "datum.b > 3"
},
Follow-up question regarding multiple filtering criteria.
You can do this with a filter transform:
{
"data": {
"values": [
{"a": "A", "b": 2, "c": "red"},
{"a": "A", "b": 7, "c": "red"},
{"a": "A", "b": 4, "c": "blue"},
{"a": "B", "b": 1, "c": "blue"},
{"a": "B", "b": 2, "c": "red"}
]
},
"transform": [{"filter": "datum.c == 'red'"}],
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "nominal"},
"y": {"aggregate": "average", "field": "b", "type": "quantitative"}
}
}
This is the output I receive via curl. I want to save 'playcount' in a variable.
How do I loop through tracks[] to get the strings 'playcount' and save them so I can form the sum? I've spend a lot of time figuring it out with jq but nothing really worked out..
{
"success": true,
"data": {
"track_count": 2,
"discs": [
{
"number": 1,
"name": "",
"tracks": [
{
"album_id": "u2hh2n2b7fo20v46cbe",
"playcount": 17212,
"name": "World Savior",
"number": 1,
"duration": 341,
},
{
"album_id": "jk299sdhjahj991nbwd",
"playcount": 9812,
"name": "Tower",
"number": 2,
"duration": 281,
}
]
}
],
"month": 11,
"day": 26,
"year": 2021,
"type": "single",
}
}
If you want the list of playcount values, you just have to drill down to the right content:
jq '.data.discs[].tracks[].playcount'
If you want their sum, make an array of that and add its entries:
jq '[.data.discs[].tracks[].playcount]|add'
A little more sophisticated as my question mentioned below.
I learned to use arrays more, but it screws things up too.
Input:
{
"a": [
{
"b": "c",
"d": "e"
},
{
"b": "f",
"d": "g"
}
],
"h": [
{
"b": "c",
"i": "j"
},
{
"b": "f",
"i": "k"
}
]
}
desired output:
{
"l": [
{
"b": "c",
"d": "e",
"i": "j"
},
{
"b": "f",
"d": "g",
"i": "k"
}
]
}
Things that I've tried, based up on JQ How to merge multiple objects into one
{ x: [ inputs | .a[] | { (.h[]): .i } ] | add}
The key to a simple solution is transpose:
[.a, .h]
| transpose
| map(add)
| {l: .}
I just started using JSONata and I found it quite fascinating to parse JSON easily. But I have this problem, and I'm not sure if it can be done with JSONata directly.
I want to include a counter that goes from 1 to "the number of objects in an array", like so:
Original output from JSONata expression:
[
{
"a": false,
"b": "",
"c": "",
"d": true
},
{
"a": false,
"b": "",
"c": "",
"d": true
},
{
"a": false,
"b": "",
"c": "",
"d": true
}
]
Wanted output:
[
{
"count": "1",
"a": false,
"b": "",
"c": "",
"d": true
},
{
"count": "2",
"a": false,
"b": "",
"c": "",
"d": true
},
{
"count": "3",
"a": false,
"b": "",
"c": "",
"d": true
}
]
Is it possible? Thank you in advance.
You can use the $map() function to iterate over a list and apply an expression to each item. The second argument of your function will be the index within the array. So for your example, the following will merge the count property into your original array of objects:
$ ~> $map(function($v, $i) {
$merge([{'count': $i+1}, $v])
})
See this working in the JSONata Exerciser: http://try.jsonata.org/rkDpyXMVM
How can i randomize my following JSON in angularjs???
{
"1": {
"id": "1",
"que": "Grand Central Terminal, Park Avenue, New York is the world's",
"options": {
"A": "largest railway station",
"B": "highest railway station",
"C": "longest railway station",
"D": "None of the above"
},
"ans": "A"
},
"2": {
"id": "2",
"que": "Entomology is the science that studies",
"options": {
"A": "Behavior of human beings",
"B": "Insects",
"C": "The origin and history of technical and scientific terms",
"D": "The formation of rocks"
},
"ans": "B"
},
"3": {
"id": "3",
"que": "Eritrea, which became the 182nd member of the UN in 1993, is in the continent of",
"options": {
"A": "Asia",
"B": "Africa",
"C": "Europe",
"D": "Australia"
},
"ans": "B"
}
}
To make your task easier i would suggest you use an array of objects like this one:
var questions=
[
{
"id": "1",
"que": "Grand Central Terminal, Park Avenue, New York is the world's",
"options": {
"A": "largest railway station",
"B": "highest railway station",
"C": "longest railway station",
"D": "None of the above"
},
"ans": "A"
},
{
"id": "2",
"que": "Entomology is the science that studies",
"options": {
"A": "Behavior of human beings",
"B": "Insects",
"C": "The origin and history of technical and scientific terms",
"D": "The formation of rocks"
},
"ans": "B"
},
{
"id": "3",
"que": "Eritrea, which became the 182nd member of the UN in 1993, is in the continent of",
"options": {
"A": "Asia",
"B": "Africa",
"C": "Europe",
"D": "Australia"
},
"ans": "B"
}
]
And then to select a random question use:
$scope.randomQuestion = questions[Math.floor(Math.random()*questions.length)];
One solution would be to convert your questions Object to an Array, so you can randomize the questions order:
http://plnkr.co/edit/PSeh0BLNjK5ydXJrLguw?p=preview
<p ng-repeat="q in questionsArray | orderBy: random">{{q.key}} - {{q.val.que}}</p>