Reputation: 1848
I am using nodejs with jsonpath. I have this json structure:
{
things:{
books: [
{name: "book1"},
{name: "book2"},
{name: "book3"},
{name: "book4"},
],
movies: [
{name: "movie1"},
{name: "movie2"},
{name: "movie3"},
{name: "movie4"},
]
}
}
I would like to know the jsonpath expression that returns an array with the key names of the things
object. That would be:
["books","movies"]
For now, I am doing this:
Object.keys(jsonpath.eval(jsonStructure,"$.things").pop());
But I don't find it elegant... I should not need to get a copy the whole structure when I only need the key names.
Upvotes: 25
Views: 21818
Reputation: 173
jsonPath has new update jsonpath-plus jsonpath-plus expands on the original specification to add some additional operators and makes explicit some behaviors the original did not spell out.
^
for grabbing the parent of a matching item
~
for grabbing property names of matching items (as array)
so to get proper output use this query things.*~
you can try here also https://jsonpath.com/
Upvotes: 13
Reputation: 173
The syntax you used for give is wrong to get keys in json path use "$.*~" ex. input: { "firstName": "John", "lastName" : "doe", "age" : 26 } output: [ "firstName", "lastName", "age" ]
Upvotes: 0
Reputation: 2181
Not exactly what you are asking for, but might still be relevant.
We use object-scan for this kind of task as it is much better suited for data processing and analyzing. Once you wrap your head around it that is (:
Anyways, here is how you could answer your question if you are willing to add another dependency
// const objectScan = require('object-scan');
const data = { things: { books: [ { name: 'book1' }, { name: 'book2' }, { name: 'book3' }, { name: 'book4' } ], movies: [ { name: 'movie1' }, { name: 'movie2' }, { name: 'movie3' }, { name: 'movie4' } ] } };
console.log(objectScan(['things.*'], { rtn: 'property' })(data));
// => [ 'movies', 'books' ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>
Disclaimer: I'm the author of object-scan
Upvotes: 1
Reputation: 33429
I don't believe there is a better solution than your own:
Object.keys(jsonpath.eval(jsonStructure,"$.things").pop());
I think the main misconception here is that you don't have to worry about this snippet "getting a copy of the whole structure", because you aren't copying the whole structure. You already have the entire object loaded into memory, jsonpath doesn't create a new copy, it simply returns a reference to the already existing object, i.e.:
jsonpath.eval(jsonStructure,"$.things").pop() === jsonStructure.things //true
Upvotes: 3