将查询字符串解析为嵌套对象

3

我有一个非常特殊的问题需要解决:

我有以下序列化查询字符串:

a=a2&b.c=c2&b.d.e=e2&b.d.f=f2

被反序列化成以下对象:

{
    a: "a2", 
    b.c: "c2", 
    b.d.e: "e2", 
    b.d.f: "f2"
}

使用以下解析器(在处理扁平对象时非常好用!)

function parse(string){
    string = 
    '{"' +  //root
        string
            .replace(/&/g, '","') //replace '&' with ','
            .replace(/=/g,'":"')+ //replace '=' with ':'\
    '"}'; //close root


return JSON.parse(string,function(key, value){ //handle URI issues

        var ret;

        if(key===""){ //null key means that we have something wrong with the encoding, probably escaped shit
            ret = value;
        }
        else{
            ret = decodeURIComponent(value); //decode escaped stuff
        }
        return ret;

});

}

需要将此解析为一个多维对象,该对象代表键中的 . 符号,如下所示:

{
    a:"a2",
    b:{
        c: "c2",
        d:{
            e:"e2",
            f:"f2"
        }
    }
}

任何帮助都将是惊人的。我已经尝试了在过去几个小时内重复这个过程,但我的大脑已经散架了,解决方案中没有任何乐趣。
如果有另一种方法将N维JavaScript对象解析为URI,然后再解析回JavaScript对象(两个函数),那么我很愿意听听建议。

2
为什么要重新发明轮子,而不使用标准的多维请求URI呢?例如:a=a2&b[c]=c2&b[d][e]=e2&... - Māris Kiseļovs
有没有数组的符号表示法?如果没有,那就创建一个新对象并分配属性。 - nhahtdh
我很乐意这样做,您能演示一下吗?我需要能够将JavaScript对象解析为URI,并从URI转换回JavaScript对象,具有无限嵌套功能。谢谢。 - Andrew Rhyne
2
这里还有 rison - georg
这就是我选择的。谢谢。 - Andrew Rhyne
2个回答

0

我在实际应用中遇到了同样的问题。这是我的解决方案:

const queryToObject = (query) => {

    return query.split('&').reduce((result, entry) => {
        const [k, v] = entry.split('=')
        const keys = k.split('.')
        let key = 'result', value = `'${v}'`
        for (i = 0; i < keys.length; i++) {
            key += `['${keys[i]}']`
            if (i == keys.length - 1) eval(key + '=' + value)
            else if (!eval(key)) eval(key + '= {}')
        }
        return result
    }, {})

}

并且

const recursiveQueryToObject = (query) => {

    const helper = (keys, value, nth) => {
        const key = keys.shift()
        if (!keys.length) return { [key]: value }
        else return { [key]: { ...nth[key], ...helper(keys, value, nth[key] || {}) } }
    }

    return query.split('&').reduce((result, entry) => {
        const [k, value] = entry.split('=')
        const keys = k.split('.')
        const key = keys.shift()
        result[key] = keys.length ? { ...result[key], ...helper(keys, value, result[key] || {}) } : value
        return result
    }, {})

}

0

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