Description
Given an object (json), write code to extract all the keys from it. This is a question that I really wanted to ask everybody for a long time ago but I did not have time to write it up. It can be helpful in some cases in your daily work.
Rule:
- You can use any parse function to get the JSON object, it does not cost you any bytes
- Since a JSON object is a data structure that is not available in some languages, you can use any kind of data that has a similar structure in your favorite language.
- To be clear, the input to your function should be a JSON object if it can.
- The object can have nested keys.
- The object can contain arrays and if it contains an array you will use the index of each element as a key.
- Output can be a list with any format but it is preferred to be line by line.
- The output keys can be arranged in any order, it does not matter.
- Shortest bytes for each language will be win.
- You can use any delimiter between each child key and its parent. Here I use
.
(please see the sample output for more detail). - The key can be a special character. For example: The input I got from @tsh
{"":{"":4,".":5},".":2,"..":3}
But this is a special case and it is not required to handle it. You are better to avoid it.
Example
Given an object:
A = {
"name" : {
"first": "jane",
"last": "doe"
},
"lang" : ["html", "css"]
}
Then the output should be:
"name"
"name.first"
"name.last"
"lang"
"lang.0"
"lang.1"
The index key (0
and 1
) are a little tricky here, so for some languages like Javascript, it can be [0]
and [1]
instead.
So the example below is also correct:
"name"
"name.first"
"name.last"
"lang"
"lang[0]"
"lang[1]"
A Sample test case:
Input:
{
"quiz": {
"sport": {
"q1": {
"question": "Which one is a correct team name in the NBA?",
"options": [
"New York Bulls",
"Los Angeles Kings",
"Golden State Warriors",
"Houston Rockets"
],
"answer": "Houston Rockets"
}
},
"maths": {
"q1": {
"question": "5 + 7 = ?",
"options": [
"10",
"11",
"12",
"13"
],
"answer": "12"
},
"q2": {
"question": "12 - 8 = ?",
"options": [
"1",
"2",
"3",
"4"
],
"answer": "4"
}
}
}
}
Output:
[
"quiz",
"quiz.sport",
"quiz.sport.q1",
"quiz.sport.q1.question",
"quiz.sport.q1.options",
"quiz.sport.q1.options.0",
"quiz.sport.q1.options.1",
"quiz.sport.q1.options.2",
"quiz.sport.q1.options.3",
"quiz.sport.q1.answer",
"quiz.maths",
"quiz.maths.q1",
"quiz.maths.q1.question",
"quiz.maths.q1.options",
"quiz.maths.q1.options.0",
"quiz.maths.q1.options.1",
"quiz.maths.q1.options.2",
"quiz.maths.q1.options.3",
"quiz.maths.q1.answer",
"quiz.maths.q2",
"quiz.maths.q2.question",
"quiz.maths.q2.options",
"quiz.maths.q2.options.0",
"quiz.maths.q2.options.1",
"quiz.maths.q2.options.2",
"quiz.maths.q2.options.3",
"quiz.maths.q2.answer"
]
This is my solution using jq:
jq -r '[paths|map(.|tostring)|join(".")]'
Full code:
jq -r '[paths|map(.|tostring)|join(".")]' file.json
The content of file.json
is an object from input
[paths|map(tostring)|join(".")]
\$\endgroup\$paths|map(@text)|join(".")
\$\endgroup\$