Whats the standard of defining an empty object in JSON - json

I have an issue with my application. It is returning a JSON file of an array of objects. The application is defining an empty object inside the array of objects as text value string whose value is defined as an object in the other element of array. Please see the value of the key "b" in the example.
For Eg:
{
"result": [{
"a": "1",
"b": {
"c1": "31",
"c2": "32"
}
}, {
"a": "5",
"b": ""
}
]
}
I want to know if that is a correct way of defining the key "b" as an empty object.
Thanks in advance!!

An empty object is defined by {}:
"b": {}
I.e. use the usual object delimiters but don't add any key-values.
What you defined is an empty string.

In JSON, an object is defined with { }, which is exactly what you would represent an empty object as.
{
"result": [
{
"a": "1",
"b": {
"c1": "31",
"c2": "32"
}
}, {
"a": "5",
"b": { }
}
]
}

Related

How to sort a JSON object with sub-objects based on an attribute of its sub-objects?

I have a list of objects that I need to index into by one of its attributes, the name in the below example. So I'm storing the list as an object instead of an array:
{
"Foo": {
"name": "Foo",
"date": "2022-08-21"
},
"Bar": {
"name": "Bar",
"date": "2022-08-20"
}
}
How can I sort the sub-objects by a different property of theirs (i.e. date in the above example), when serializing this JSON?
By definition, the keys within a JSON object are semantically unordered, so implementations are not required to support explicit sorting of such keys in any way.
However, as of version 1.4, jq does preserve the order of keys within objects, and also respects the order in which they are added. So, for the problem at hand, it becomes a matter of converting the above representation into an array, sorting it, and converting it back to a JSON object:
jq 'to_entries | sort_by(.value.date) | from_entries'
Explanation
First, convert the object with sub-objects into an array of key/value pairs with to_entries. The input becomes:
[
{
"key": "Foo",
"value": {
"obj1.name": "Foo",
"obj1.date": "2022-08-21"
}
},
{
"key": "Bar",
"value": {
"obj2.name": "Bar",
"obj2.date": "2022-08-20"
}
}
]
Since we now have an array, we can sort it with an arbitrary sub-object selector in sort_by, in my example, by .value.date, the output becomes:
[
{
"key": "Bar",
"value": {
"obj2.name": "Bar",
"obj2.date": "2022-08-20"
}
},
{
"key": "Foo",
"value": {
"obj1.name": "Foo",
"obj1.date": "2022-08-21"
}
}
]
Now it's a matter of converting the key/value form back to the object form with from_entries. The output becomes:
{
"Bar": {
"name": "Bar",
"date": "2022-08-20"
},
"Foo": {
"name": "Foo",
"date": "2022-08-21"
}
}

Get array with all values for certain key in JSON wih JQ

Say I have the following JSON:
{
"a": 0,
"b": "c",
"d": {
"e": {
"f": "g",
"comments": {
"leading": "Lorem ipsum"
},
"h": {
"i": {
"j": [
1,
2
]
},
"comments": {
"trailing": "dolor sit"
}
}
},
"comments": {
"leading": "amet."
}
}
}
I want to get an array with the values of all the fields named comments (which can be nested in any level). So, in this case I want to get:
[
{
"leading": "Lorem ipsum"
},
{
"trailing": "dolor sit"
},
{
"leading": "amet."
}
]
The order of the array doesn't matter.
How can this be achieved with jq? I have only performed basic stuff with it and haven't been able to produce anything close to what I need.
Thanks in advance ☺️
You can use the getpath function. Use paths to identify all the paths leading upto .comments and get the paths' value
jq '[ getpath ( paths | select( .[-1] == "comments" ) ) ]'
Or use a recursive descent to filter objects containing .comments and get its value
jq '[ recurse | select(has("comments")?).comments ]'

Add a new key/value to every object in json array in file with jq

I have a json file like below. I want to add "stable": "yes" to every object in this file with jq. How can i do this?
[
{
"id":"1",
"name":"Blue"
},
{
"id":"2",
"name":"Red"
}
]
I want it to be like this:
[
{
"id":"1",
"name":"Blue",
"stable": "yes"
},
{
"id":"2",
"name":"Red",
"stable": "yes"
}
]
map and + will do this:
$ jq 'map(. + {stable: "yes"})' tmp.json
[
{
"id": "1",
"name": "Blue",
"stable": "yes"
},
{
"id": "2",
"name": "Red",
"stable": "yes"
}
]
Since the input is an array, the . refers to each object in that array, to which we add another object.
Note this will also override any existing stable key in each object.

Get a object from json based on a specific value

I have a json string. I need to get a specific object based on an id value. Suppose I entered 2, then I want {"id":"2","name":"def"} as the result. I want this to be done in java class.
[
{"id":"1",
"name":"abc"},
{"id":"2",
"name":"def"}
]
Put the Objects in the Array for better manipulation..!!!
JSONObject data = new JSONObject(YOUR_JSON);
JSONArray data_Values=data.getJSONArray(values);
int n=2;// Entered ID
for(int i=0;i<=data_Values.length();i++)
{
if(n==data_Values.getInt("id"))
{
id=data_Values.getInt("id");
name=data_Values.getString("name");
}
}
JSON Data
{
"Values": [
{
"id": "1",
"name": "ABC"
},
{
"id": "2",
"name": "EFG"
},
{
"id": "3",
"name": "HIJ"
}
]
}

Extracting a subset of attributes with JSONPath

I have this JSON code:
{
"A": {
"AB": [{
"ABA": "0",
"ABB": "1",
"ABC": "2"
}]
}
}
I need to use a JSONPath expression that returns that JSON with only ABA and ABC attributes. Something like:
{
"A": {
"AB": [{
"ABA": "0",
"ABC": "2"
}]
}
}
So far I manage to extract either one or all attributes. For example
$.A.AB[*]
or
$.A.AB[*].ABA
Is there a way to extract only two?
Thanks
This will work using the Jayway implementation (Java):
$.A.AB[*]['ABB', 'ABA']
and the result for your input would be:
[
{
"ABB" : "1",
"ABA" : "0"
}
]
You can Compare different providers here:
http://jsonpath.herokuapp.com/