-1

I have a JSON structure of nested locations like this: (note, this is pseudo-json, not actual json)

location : "Location Parent"
locationid : 100
parent_location_id: ''

SUBLOCATIONS : Array(2)
    location : "Location Child"
    locationid : 200
    parent_location_id: 100

    location : "Location Child Two"
    locationid : 300
    parent_location_id: 100

location : "Location Parent Two"
locationid : 101
parent_location_id: ''

SUBLOCATIONS : Array(2)
    location : "Location Child"
    locationid : 201
    parent_location_id: 101

    location : "Location Child Two"
    locationid : 301
    parent_location_id: 101

    SUBLOCATIONS : Array(2)
        location : "Location Sub Child"
        locationid : 401
        parent_location_id: 301

        location : "Location Sub Child Two"
        locationid : 501
        parent_location_id: 301

I want to be able to recurse through this data and add an attribute to each item that denotes its position or depth in the hierarchy, so in the end, I'll have something like this:

location : "Location Parent"
locationid : 100
parent_location_id : ''
level: 1

SUBLOCATIONS : Array(2)
    location : "Location Child"
    locationid : 200
    parent_location_id : 100
    level: 2

    location : "Location Child Two"
    locationid : 300
    parent_location_id : 100
    level: 2

location : "Location Parent Two"
locationid : 101
parent_location_id : ''
level: 1

SUBLOCATIONS : Array(2)
    location : "Location Child"
    locationid : 201
    parent_location_id : 101
    level: 2

    location : "Location Child Two"
    locationid : 301
    parent_location_id : 101
    level: 2

    SUBLOCATIONS : Array(2)
        location : "Location Sub Child"
        locationid : 401
        parent_location_id: 301
        level: 3

        location : "Location Sub Child Two"
        locationid : 501
        parent_location_id: 301
        level: 3

I can recurse through the structure like this:

  recursivelyTraverseLocations(locations) {

        for (let location of locations) {

            if (location.parent_location_id > 0) {
                location.level = _depth_
            } else {
                location.level = 1
            }

            if (location.SUBLOCATIONS) {
                this.recursivelyTraverseLocations(location.SUBLOCATIONS);
            }
        }
      }

But I can't wrap my head around how to initialize and scope the depth variable to count how deep it is in the recursion and reset when it hits the bottom and is starting at the top of a new branch.

Blue
  • 22,608
  • 7
  • 62
  • 92
Stephen R. Smith
  • 3,310
  • 1
  • 25
  • 41
  • 1
    Start with `1` and pass it as a parameter to the recursive method – Thiyagu Feb 01 '18 at 17:48
  • 1
    That's not [JSON](https://json.org). _"JSON is a textual, language-indepedent data-exchange format, much like XML, CSV or YAML."_ - [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – Andreas Feb 01 '18 at 17:50
  • @Andreas - I'm getting data from a service in JSON format, then presumably by assigning it to a variable it becomes simply a JavaScript object, so would the correct title be 'Adding Depth or Parent Count attribute to a nested JavaScript object structure'? I noted at the top that my example was pseudo-json, but I'm not sure exactly how to most accurately describe this. Thanks! – Stephen R. Smith Feb 01 '18 at 18:02
  • Well, if you're getting the data from a service in JSON format, why can't you copy and paste that JSON into the question? Why make us look at pseudo-code? Or just put the curly and square brackets in there and call it a JavaScript object? – Heretic Monkey Feb 01 '18 at 18:04
  • [This question and its answers](https://stackoverflow.com/q/13523951/215552) should help you find the answer, anyway. – Heretic Monkey Feb 01 '18 at 18:06
  • @MikeMcCaughan Posting the specific data would violate an NDA, so I mocked up a demonstrative sample. If it's better etiquette to make it exact, I can do that. – Stephen R. Smith Feb 01 '18 at 18:07
  • @user7 Your answer solved the problem - thanks! I've updated the question with the solution, if you can post your answer as an answer instead of a comment, I can accept it as the best one. – Stephen R. Smith Feb 01 '18 at 18:26
  • Why do you provide JSON in non-JSON format? Is that to test our ability to convert it back to JSON? Why not just post JSON in your question? – trincot Feb 01 '18 at 18:28
  • [You do not need to mark questions as "SOLVED" via editing the title](//meta.stackexchange.com/a/116105/295637), or [posting updates/thanks in posts](//meta.stackexchange.com/a/109959/295637). Simply add your own answer, and mark as accepted. Anything additional can be perceived as noise for future visitors. See: [Can I answer my own question?](//stackoverflow.com/help/self-answer). – Blue Feb 01 '18 at 18:32

1 Answers1

0

where data is returned from a service, and iteratorDepth is defined as a private variable:

Call:

this.locations = this.recursivelyTraverseLocations(data,1)

and modify the function to take the interatorDepth as a parameter

this.recursivelyTraverseLocations(locations, iteratorDepth) {

        for (let location of locations) {

            if (location.parent_location_id > 0) {
                location.level = iteratorDepth
            } else {
                location.level = 1
            }

            if (location.SUBLOCATIONS) {
                this. this.recursivelyTraverseLocations(location.SUBLOCATIONS, iteratorDepth+1);
            }
        }
        return locations;
    }

This correctly sets the level attribute on each object in the hierarchy.

Stephen R. Smith
  • 3,310
  • 1
  • 25
  • 41