递归Javascript

3

给定以下数据结构:

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

我如何递归遍历它并在遇到URL时生成一个“路由”对象?我还需要跟踪一个路由的父级,因此:
var Route = function(name, url, parents) {
}

在这里,name是关键字(例如,在顶层中为“orders”或“users”),url是显而易见的,“parents”则是一些在我们每个级别下钻取时生成的堆栈。

我试过几次写这个,但遇到了变量作用域/按引用传递属性与值以及各种其他奇怪的问题。

数据结构也不是固定的,但需要包含该信息。

2个回答

2
这是一个例子。
   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);

谢谢,我会在周一测试后授予答案! - Samuel
不必使用 typeof=== 进行判断。 - Rudie
1
为什么不必要呢?因为typeof的结果始终是一个字符串,所以没有必要进行类型检查... ===是好的,但并不总是必要的。在这里的某个地方解释了为什么不总是使用=== - Rudie
1
"== 有什么优势?我认为 === 不会进行任何转换,而 == 则会进行转换。" - Mic

0
以下代码将把数据结构映射为一个Route对象列表,每个对象包含相应的nameurlparents列表。
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, [], []);

谢谢,我会在周一测试这个答案和另一个答案,并授予最优雅的那个 :) - Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接