3

Scenario I am looking to find a path such as myObject.authors[2].name by starting at a dynamic point in a JSON object (think of it as a string). Take the following, for example:

I have this JSON:

var myOject = {  
   "title":"My New Post",
   "authors":[  
      {  
         "name":"Smith",
         "description":"Name is smith"
      },
      {  
         "name":"Jones",
         "description":"Name is {{#reverseParse name}}"
      },
      {  
         "name":"Lincoln",
         "description":"Name is Lincoln"
      }
   ]
}

And I would like to use a custom handlebars.js helper or JS function to find dynamic attributes such as the name: {{#reverseParse **name**}}. So it would replace {{#reverseParse name}} with Jones.

Potential Solutions

I would be surprised if there isn't a pre-existing solution to this since it seems like it would be a common encounter. However, I've been unable to find some. Are there any?

I thought about just creating a reverse parser that would find the function name reverseParse and start parsing the string backwards and construct the path as it goes.

Q How can I get the JSON path from a dynamic variable in the same JSON (think of it as a string)?

PS - let me know if I can clarify in any way. Thanks!

EDIT An example function signature could be something like this: var reverseParse = function([string] myString) { var jsonPath; ... // find string position of {{#reverseParse [variable]}} // start parsing the string from that position to the left // as you encounter JSON characters, acknowledge and construct path // etc? return jsonPath; }

where the string argument should actually be JSON formatted.

karns
  • 4,469
  • 5
  • 24
  • 45
  • I don't quite follow. Are you creating the JSON object by hand? Why not dynamically create the object and then JSON.stringify() it? – jrader Mar 09 '16 at 18:16
  • Our case is extremely hard to explain. So we are using handlebars and our template is the same as the JSON that it uses. Does that make sense? So if you look at the JSON in my OP, it acts as both the template to parse and the JSON to use with the parsing. {{#reverseParse name}} should be able to grab myObject.authors[2].name. That's why I stressed the benefit of imagining the JSON as a string/template. Does that help? – karns Mar 09 '16 at 18:21
  • I don't understand what you start with and what you are trying to get. Could you please clarify your question by providing a function signature? For example, if your question could be made equivalent to coding a function f that takes parameters a and b of types A and B, and returns a value v of type V, I think it would be much clearer. – vinntec Mar 09 '16 at 18:24
  • @karns that does help a little. I'm not very familiar with handlebars.js. I just read up a little on it. So to clarify...do you get this template as a response to an AJAX request? What level of control do you have over this template? – jrader Mar 09 '16 at 18:36
  • @jrader - we can forget the fact that we are using Handlebars.js. To really simplify the question, I just when to find a keyword in a string and parse backwards constructing a json path. IE: test={name:'john',authors:[{name:jeremy},{name:blair},{name:KEYWORD}]}; which would return test.authors[2].name – karns Mar 09 '16 at 18:49
  • @vinntec - signature *could* be something like so: ` var reverseParse = function([string] myString) { var jsonPath; ... return jsonPath; } ` – karns Mar 09 '16 at 18:52
  • This post might possibly be what you're looking for ... http://stackoverflow.com/questions/8790607/javascript-json-get-path-to-given-subnode – jrader Mar 09 '16 at 18:57
  • @jrader - I saw that one. In this situation I CANNOT use absolute JSON path with the variable. It needs to be dynamically constructed since at some point in the path there may be arrays of which it is unknown which index the path should use. Understandable? – karns Mar 09 '16 at 19:00
  • 1
    It might be best just to loop over your objects and do the replacement. Since you aren't sure where it would occur in a json object, maybe regular ol' recursion is the way to go while modifying under the array's scope? – Corvus Crypto Mar 09 '16 at 19:08
  • @CorvusCrypto - While this would certainly be possible, it would be extremely intensive and mal-performant. I would like to see a more efficient solution. – karns Mar 09 '16 at 19:11
  • 1
    @karns in what way would it be intensive and/or mal-performant? You would have to traverse the JSON tree anyways if you are going to dynamically create a reverse path to every node – jrader Mar 09 '16 at 19:16
  • 1
    @karns I don't think it would really be mal-performant. You're still getting O(N*k) performance if you only act upon array elements with k replacements. Acting upon the json as a string doing RegExp with multiple backward checks with captures is going to be much worse – Corvus Crypto Mar 09 '16 at 19:18
  • @CorvusCrypto - Perhaps you guys are right, I would have to think about the complexities a little more to get a better understanding. How did you get O(N*k) complexity? I figured it would be something of exponential complexity, but I most certainly could be wrong. If the JSON object had N attributes with K arrays which in turn could be arrays... ? IDK, that stuff is a little over my head to figure out. – karns Mar 09 '16 at 19:28
  • I got O(n*k) because you have N array elements (objects) total you might need to do replacement on and you need to replace as a string k times for each {{#reverseparse _}} you encounter (if using regexp), thus you scan through about N*k times and your time complexity increases as such as well. I should have mentioned that just traversing the tree will give you O(N) roughly since you can just modify the object while on that node and there is no need for repetitive scanning – Corvus Crypto Mar 09 '16 at 19:36
  • @CorvusCrypto - Good points, very well. So what you are saying is that I loop through the object (recursively for nested objects) and just check if any object attribute contains the "{{reverseParse ...}}" and if it does replace it with the current set of variables that are being tracked in the loops, correct? – karns Mar 09 '16 at 19:44
  • yep! and at the worst case you still visit each node only once so it is not so bad :) – Corvus Crypto Mar 09 '16 at 19:52
  • @CorvusCrypto - okay, I'll give it a shot! Could you try to explain why it is N*K again, please? Your original explanation didn't hit it home for me. – karns Mar 09 '16 at 20:00
  • 1
    @karn to avoid a long discussion please see this answer here (and the longer of the comments accompanying it) http://stackoverflow.com/questions/5892115/whats-the-time-complexity-of-average-regex-algorithms. The *k comes in when you do replacements since you need to re-scan through the string during replacement (so really it becomes O(N*(k+1))). Keep in mind this is only if you handle the JSON as a string. if you parse it instead, then traverse, it is only O(N) for these operations. – Corvus Crypto Mar 09 '16 at 20:17

0 Answers0