4

I am pretty new to JQ ... so sorry if it seems obvious.. The bare problem first. I have this JSON file:

Link: https://github.com/mariotti/technical_interview_questions/blob/master/QUESTIONS.json

Extract.

cat QUESTIONS.json | jq '.TechQuestions.category[0,1].question[0,1]'
output:
{
ID: Q1,
categoryname: General,
idC: C1,
idCQ: C1Q1,
idQ: Q1,
title: Find the most frequent integer in an array
}
{
ID: Q21,
categoryname: Strings,
idC: C2,
idCQ: C2Q1,
idQ: Q1,
title: Find the first non-repeated character in a String
}
{
ID: Q2,
categoryname: General,
idC: C1,
idCQ: C1Q2,
idQ: Q2,
title: Find pairs in an integer array whose sum is equal to 10 (bonus; do it in linear time)
}
{
ID: Q22,
categoryname: Strings,
idC: C2,
idCQ: C2Q2,
idQ: Q2,
title: Reverse a String iteratively and recursively
}

As you can see, this is "deep" into:

{
"TechQuestions": {
"category": [
  {
    "catname": "General",
    "idC": "C1",
    "question": [
      {
        "ID": "Q1",
        "categoryname": "General",
        "idC": "C1",
        "idCQ": "C1Q1",
        "idQ": "Q1",
        "title": "Find the most frequent integer in an array"
      },

I want to add the key/field:

"codefile" : "a string to be defined"

within the question[] items to get something like:

      {
        "ID": "Q1",
        "categoryname": "General",
        "idC": "C1",
        "idCQ": "C1Q1",
        "idQ": "Q1",
        "title": "Find the most frequent integer in an array",
        "codefile" : "not present"
      },

And I want to do it programmatically as I might need to develop a bit further...

From other sources (Transforming the name of key deeper in the JSON structure with jq) I could for example rename a key with this:

cat QUESTIONS.json | jq '.' | jq '
# Apply f to composite entities recursively, and to atoms
def walk(f):
 . as $in
 | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;
(.  |= walk(
           if type == "object"
           then with_entries( if .key == "name" then .key |= sub("name";"title") else . end)
           else .
           end))'

I was trying to modify this bit without success. It seems I am unable to simply add a key/value!

I will avoid to overload you with odd references and a further list of attempts. But maybe I give you an example of a try:

(.  |= walk(
       if type == "object"
       then with_entries(
            if .key == "question"
            then . = ( . + {"freshly": "added"})
            else .
            end)
       else .
       end))'

The solution doesn't have to match my attempts. Actually if there is a more straight full way it is very appreciated.

1 Answer 1

4

What's wrong with:

.TechQuestions.category[0,1].question[] += {"codefile" : "a string to be defined"}

Using walk/1, you could consider:

walk( if type == "object" and has("question")
      then .question[] += {"codefile" : "a string to be defined"}
      else .
      end)
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot! Both are working nicely. Probably with the first line, I was trapped into trying to walk/select first... which is indeed the second bit. Where indeed I was trapped into a "with_entries". Perfect! I would like to report anyway funny behaviour: the order of the key is not preserved, if you just filter from file to file. The funny thing is that it is seems not consistent.
To help others, in case they step in this question. For me it was difficult to understand that '.TechQuestions.category[].question[]' is a filter but also the RHS of an operation.
@mariotti - I think you meant to write "LHS". The alteration of the key ordering is potentially a nuisance, but semantically it should not be an issue. You might, however, want to consider the -S command-line option.
A similar problem was here: stackoverflow.com/questions/37904796/…
ops, yes: LHS. I am left handed with an age. They spent time to teach me that I confuse L and R ;) .. and I keep happily confusing. I think that the issue is just because I am very new to jq. The order (sorting), indeed might help in developing. For example I executed both of your lines above and compared the output with "diff". They differ. And I am a bit old style.. I expect no difference. Of course the JSON data are exactly the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.