我知道有更好的方法,但我没有看到它。解析子网址

时间:2014-05-20 08:13:48

标签: javascript algorithm loops

有关如何更改此列表的任何想法

// How to get from this urls
[
     '/this',
     '/should/not',
     '/should/close',
     '/should',
     '/not/be/that',
     '/this/is'
]

进入这个结构?

// To this in a smart way
[
    {
        url: 'this',
        sub: [{
            url: 'is'
        }]
    },
    {
        url: 'should',
        sub: [{
            url: 'not'
        },{
            url: 'close'
        }]
    },
    {
        url: 'not',
        sub: [{
            url: 'be',
            sub: [{
                url: 'hard'
            }]
        }]
    }
]

我不是因为速度问题,而且我已经有了一个正在运行的解决方案(在第一级使用for循环迭代,然后在下一级别上等,并建立结果)但是一直在想那里只需几行代码就可以做到这一点。

是吗?

Larsi

3 个答案:

答案 0 :(得分:1)

我有这个"解决方案",以防你可以使用不同的格式:

var a = [
     '/this',
     '/should/not',
     '/should',
     '/not/be/that',
     '/this/is'
],
b = {};

for(var i = 0; i < a.length; i++){
    var items = a[i].replace('/','').split('/');
    var temp = {};
    b[items[0]] = temp;
    for(var j = 1; j < items.length; j++){
        temp[items[j]] = {};
        temp = temp[items[j]];
    }
}

结果:

{
    "this": {
        "is": {}
    },
    "should": {},
    "not": {
        "be": {
            "that": {}
        }
    }
}

答案 1 :(得分:1)

我同意Cerbrus所说的建议结构很糟糕,但这是一次尝试:

    var dir = [
         '/this',
         '/should/not',
         '/should',
         '/not/be/that',
         '/this/is'
    ];

    var res = [];

    function subify(s) {
        if (s == "") return {url: ""};
        if (s[0] == "/") s = s.substr(1);

        var i = s.indexOf("/", 0);

        if (i < 0) return {url: s}
        return {url: s.substr(0, i), sub: subify(s.substr(i + 1))};            
    }

    for (var i = 0; i < dir.length; i++) {
        var s = subify(dir[i]);            // create object
        if ("sub" in s) res.push(s);       // filter out non-subs
    }

你可以通过一些花哨的正则表达式替换来接近单行。此代码将在您的路径上工作,但如果有斜杠,则不会。它也不会强制它在开始时是一个斜线;该信息将丢失。

答案 2 :(得分:0)

您可以尝试一些递归映射算法:

function mapurl (a){
  var aa = a.replace(/^\//,'').split('/'), obj = {url: aa[0]};
  if (aa.length>1) { 
    var x= [];  
    mapurl.call(x, aa.slice(1).join('/')); 
    obj.sub = x; 
  }
  this.push( obj );
  return a;
}
var urls2objs = [];
[
 '/this',
 '/should/not',
 '/should/close',
 '/should',
 '/not/be/that',
 '/this/is'
].map(mapurl, urls2objs);
//=> now urls2objs contains an array of objects 
     ( [{url: ...,  sub: [{url:..., sub:...}] }