What I want to do is 'walk' on my json, and for each key named 'base', add a key which is the full 'path' of this key.
This is my JSON:
{
"entity": {
"product": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": ["product", "products", "pdt", "pdts"]
}
},
"rabbit": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": ["rabbit", "rabbits"]
}
}
}
}
And I want a result like this :
{
"entity": {
"product": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": ["product", "products", "pdt", "pdts"],
"path": "entity.product.title"
}
},
"rabbit": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": ["rabbit", "rabbits"]
"path": "entity.rabbit.title"
}
}
}
}
Actually, I achieve this, but I get only one sub key:
walk(if type == "object" and .base then keys[] as $k | .base |= {path: $k} else . end)
Results:
{
"entity": {
"product": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": {
"path": "base"
}
}
},
"rabbit": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": {
"path": "base"
}
}
}
}
}
I also tried this:
walk(if type == "object" and .base then paths(..) as $v | .base |= {path: $v} else . end)
Results:
{
"entity": {
"product": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": {
"path": [
"base",
3
]
}
}
},
"rabbit": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": {
"path": [
"base",
1
]
}
}
}
}
}
Your advice and expertise is greatly appreciated!
CodePudding user response:
Here is one way:
reduce paths(objects | has("base")) as $p (.;
setpath($p ["path"]; $p | join("."))
)
CodePudding user response:
You can get an array representation of the path using path
, join it using join
(assuming simple, identifier-like field names), and set it using setpath
:
jq '
reduce path((.. | objects | select(.base))) as $p (.;
setpath($p ["path"]; $p | join("."))
)
'
{
"entity": {
"product": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": [
"product",
"products",
"pdt",
"pdts"
],
"path": "entity.product.title"
}
},
"rabbit": {
"att": {
"number_of_values": "Number of values"
},
"title": {
"base": [
"rabbit",
"rabbits"
],
"path": "entity.rabbit.title"
}
}
}
}
CodePudding user response:
This was a real learning experience about path
, paths
, setpath
and objects
. Before reading the other answers, I apparently re-implemented setpath
:
def add_path(p; val):
if p|length == 0
then .path = val
else .[p[0]] |= add_path(p[1:]; val)
end;
reduce ([paths(..) | select(last == "base")] | unique | map(.[:-1]))[] as $path (.;
add_path($path; ($path | join(".")))
)