For loop for every object Jq - json

I'm trying to compare two attributes on every object. This is the code i use for this problem:
(.result[].downlaodable or .result[].playable) but this time jq does cartesian product. If i have 3 object, jq turns me 9 object.
I have to convert it to something like this:
(.result[1].downlaodable or .result[1].playable)
(.result[2].downlaodable or .result[2].playable)
(.result[3].downlaodable or .result[3].playable)
How can i do that?

Change your filter to generate the results once.
.result[] | .downloadable or .playable

Related

GREL multivalued JSON

I have a column with following contents in Open Refine
1. {"result":"Mango"}
2. {"result":"Banana"},{"result":"Apple"}
and I need resulting column
1. Mango
2. Banana | Apple
The expression I tried was
"forEach(value.parseJson().result).join(' | ')"
but this does not produce results.
Your second example isn't valid JSON, so I'm not sure what the parse will produce -- probably just the first object. One approach would be to wrap each cell with square brackets ([]) to turn it into a JSON array. This will give you something that forEach can operate on.
Thanks #Tom Morris
Modified cells as
1. [{"result":"Mango"}]
2. [{"result":"Banana"},{"result":"Apple"}]
Then solution used was
forEach(value.parseJson(),v,v.result).join(' | ')

Is there a way to get the path to a specific element within the JSON value?

Given this simple example from the jq manual:
[
{
"name":"JSON",
"good":true
},
{
"name":"XML",
"good":false
}
]
using this expression:
.[1].name
I get "XML" as output.
And the question: in xpath, for example, there are ways to do the reverse: given an element, an xpath function will return the xpath to the element within the document. Is there a way to do that with jq? That is, given "XML", is there a way to get
.[1].name
as the output?
I am aware of the getpath(PATHS) function, but unless I'm missing something, that's not it.
As far as I'm concerned JQ still doesn't have a built-in for that. However, if a path in .[1]["name"] format is also acceptable, that's pretty easy:
get paths in array form using path built-in,
enclose each path component of type string in double quotes; tojson can be used for that,
join all components by ][,
and put the result between .[ and ].
path(recurse | select(.=="XML")) | ".[\(map(tojson) | join("]["))]"
Online demo
To get the JSON representation of the path(s) of interest, you could write:
paths as $p
| select(getpath($p) == "XML")
| $p
This form is normally the most useful, but it’s easy to transform it into another form if need be, as shown in #OguzIsmail's answer (see also below).
If only the path of the first occurrence is desired, you can simply use first(...), but of course there are different possible conceptions of “first”.
Producing jq-style path expressions
As pointed out by #OguzIsmail, tojson can be used to produce jq-style path expressions (i.e., jq expressions that can be used to fetch a value directly, without getpath), e.g. by adding the following to the above pipeline :
".[" + (map(tojson)|join("][")) + "]"

Gathering all root to leaf values along every path in a tree-like json object with JQ

Gathering all root to leaf values along every path in a tree-like json object with JQ. It seems like this should be easy with the walk or flatten functions, but I can't figure it out despite some helpful questions that have already been asked.
I have this
{
"cond1":["a","b","c"],
"cond2":["a1","b2","c"],
"cond2":["a","b","c3"]
}
I want this
["cond1","a"]
["cond1","b"]
["cond1","c"]
["cond2","a1"]
["cond2","b2"]
["cond2","c"]
["cond2":"a"]
["cond2":"b"]
["cond2":"c3"]
Similar questions:
https://github.com/stedolan/jq/issues/646
jq - How do I print a parent value of an object when I am already deep into the object's children?
Also, how would the answer be different if instead of ["a","b","c"] the array consisted on nested objects i.e. [["x2","x3"],["x1,"x2"]]
The key to answering both questions is paths.
For example, the following filter produces the desired output in the first case:
paths as $p
| getpath($p)
| select(scalars)
| ($p | map(select(type=="string"))) + [.]
The same filter can be used with any valid JSON as input. Replacing .cond2 with a valid nested array along the lines shown in the Q, the output would be:
["cond1","a"]
["cond1","b"]
["cond1","c"]
["cond2","x2"]
["cond2","x3"]
["cond2","x1"]
["cond2","x2"]

Using jq select elements with keys containing some string, key preserved in results

I have a JSON content as embedded in this link jq-play. The JSON content is large and couldn't be accommodated here.
Currently, I manage to get the values by
[.[keys[] | select(contains("VMIMAGE"))]]
but the key names, i.e. CP-COMPUTEENGINE-VMIMAGE-F1-MICRO aren't present in the result. How do I get it?
It looks like you want to take a "slice" of the object by selecting just those keys containing a certain string. Using your query as a model, this can most easily be accomplished using a query of the form with_entries( select(...) ), e.g.:
.gcp_price_list
| with_entries( select(.key|contains("VMIMAGE")))

Combine all boolean response of JSON objects to one with Jq

i have huge json data, in every object has download_able and playable attribute which is boolean type.
So i try to compare each other every objects attribute and get only one response.
jq '.result[].downlaodable or .result[].playable' response me like that
true
true
true
I want to compare these response again and i have to get one response.
But i can't do that. How can i do that?
I'm not sure I understand the question, but I think you want to do a boolean or of the results you get with your existing jq program. This is how you'd do it:
jq '[.result[].downlaodable or .result[].playable] | any'
This should just output: true