2

Given a data structure as follows:

var endpoints = {
    // top level
    "orders": {
        url: "/orders",
        // child
        "sub-level": {
            url: "/sublevel"
        }
    },
    // users
    "users": {
        url: "/users",
        // child
        "another-sublevel": {
            url: "/another-sublevel"
        }
    }
}

How could I recurse over this generating a "Route" object each time I encounter a URL? I also need to track the parents to a route, so:

var Route = function(name, url, parents) {
}

Where name is the key (e.g. "orders" or "users" in the top level) url is obvious and "parents" is some sort of stack that's generated as we drill down each level.

I've had a couple of goes at writing this and I'm running into trouble with variable scope / passing attributes by reference vs. value and all sorts of other weirdness.

The data structure is not fixed either, but needs to contain that information.

0

2 Answers 2

1

Here's an example

   function recurse(obj, parents){
        var prop;
        parents = parents || [];
        for(prop in obj){
            if(typeof(obj[prop]) === 'string' && prop === 'url'){
                //do something with url
                console.log(obj[prop], parents.join('->'));
            }else{
                parents.push(prop);
                recurse(obj[prop], parents);
                parents = [];
            }
        }
    }

    recurse(endpoints);
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, will test on Monday then award answer!
(Using === with typeof is not necessary.)
WHy it's NOT necessary? Because the result of typeof is ALWAYS a string, so there's no need to type check... === is good, but it's not always necessary. Somewhere on here is why it's good to not ALWAYS use ===.
What is the advantage of == ? I thought === doesn't make any conversions, while == makes it.
0

The following code will map the data structure into a list of Route objects, each containing the belonging name, url and list of parents:

function mapRoutes(endpoints, parents, routes) {
  var name, url;

  for (name in endpoints) {
    if (!endpoints.hasOwnProperty(name) || name === 'url') {
      continue;
    }   

    url = endpoints[name]['url'];

    routes.push(new Route(name, url, parents));

    mapRoutes(endpoints[name], parents.concat([name]), routes);
  }

  return routes;
}

var routes = mapRoutes(endpoints, [], []);

1 Comment

Thanks, will test this answer and the other one on Monday and award to the most elegant :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.