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

时间:2013-09-06 07:11:42

标签: javascript json parsing recursion

我有一个非常独特的问题,我试图解决:

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

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对象(两个函数),我很满意。

3 个答案:

答案 0 :(得分:1)

您可以序列化您的javascript对象并对其进行网址编码,请参阅以下类似问题的答案:Standardized way to serialize JSON to query string?

答案 1 :(得分: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
    }, {})

}

答案 2 :(得分:-1)

找到一种非常好的方法来处理这种情况:

http://mjtemplate.org/examples/rison.html

对于其他需要类似解决方案的人来说!