2017-03-31 4 views
2

hinzufügen Ich bin ziemlich neu in JQ ... so leid, wenn es offensichtlich scheint .. Das nackte Problem zuerst. Ich habe diese JSON-Datei:jq: wie ein Objekt, Schlüssel/Wert in einem verschachtelten JSON-Baum mit Arrays

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

Extrakt.

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 
} 

Wie Sie sehen können, ist dies "tief" in:

{ 
"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" 
     }, 

ich den Schlüssel/Feld hinzufügen möchten:

"codefile" : "a string to be defined" 

innerhalb der Frage [] Elemente zu erhalten etwas wie:

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

Und ich möchte es programmati tun nisch, wie ich ein bisschen weiter entwickeln könnte müssen ...

aus anderen Quellen (Transforming the name of key deeper in the JSON structure with jq) ich zum Beispiel einen Schlüssel mit dieser umbenennen könnte:

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))' 

ich dieses Bit ohne Erfolg zu ändern versuchte. Es scheint, dass ich keinen Schlüssel/Wert hinzufügen kann!

Ich werde vermeiden, Sie mit ungeraden Referenzen und eine weitere Liste von Versuchen zu überlasten. Aber vielleicht gebe ich Ihnen ein Beispiel für einen Versuch:

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

Die Lösung verfügt nicht über meine Versuche, entsprechen. Wenn es einen geradlinigeren Weg gibt, wird es sehr geschätzt.

Antwort

2

Was ist los mit:

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

Mit walk/1, könnten Sie betrachten:

walk(if type == "object" and has("question") 
     then .question[] += {"codefile" : "a string to be defined"} 
     else . 
     end) 
+0

Vielen Dank! Beide funktionieren gut. Wahrscheinlich in der ersten Zeile war ich gefangen in dem Versuch, zuerst zu gehen/auszuwählen ... was in der Tat das zweite Bit ist. Wo ich tatsächlich in einem "with_entries" gefangen war. Perfekt! Ich möchte trotzdem komisches Verhalten melden: Die Reihenfolge des Schlüssels bleibt nicht erhalten, wenn man nur von Datei zu Datei filtert. Das Lustige ist, dass es nicht konsequent erscheint. – mariotti

+0

Um anderen zu helfen, falls sie in diese Frage treten. Für mich war es schwierig zu verstehen, dass ".TechQuestions.category []. Question []" ein Filter ist, aber auch der RHS einer Operation. – mariotti

+0

@mariotti - Ich denke, Sie wollten "LHS" schreiben. Die Änderung der Schlüsselreihenfolge ist möglicherweise ein Ärgernis, aber semantisch sollte es kein Problem sein. Möglicherweise möchten Sie jedoch die Befehlszeilenoption -S in Betracht ziehen. – peak

Verwandte Themen