getPathValue() function for deep objects with arrays and with packed JSON

江枫思渺然 提交于 2019-12-02 03:27:11

问题


For background, please refer to this question: Access deep object member of embeded JSON

The solutions offered there worked very well with the packed JSON contained in key values.

However, they don't handle the situation where JSON has arrays.

The original function I referenced in the other question DID handle arrays, but it would not handle the packed JSON.

This is the original function:

function getPathValue(obj, path) {
    return new Function('_', 'return _.' + path)(obj);
}

and this is the answer from the first question:

function getValue(object, path) {
    return path
        .split('.')
        .reduce((o, k) => (typeof o === 'string' ? JSON.parse(o) : o)[k], 
object);
}

Again, both work well, but neither offers the whole package.

I need a solution that will do both and it must work in IE11's ES5.

Here is a sample API returned JSON string:

{"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"}

I'd like to be able to query values with a path string, for example:

value = getPathValue(obj, 'batters.batter[2].id');

or

value = getPathValue(obj, 'type');

or

value = getPathValue(obj, 'data.domain');

回答1:


You could replace the brackets and take the remaining values as keys. Inside of the reducing, you could use a default object for not given objects.

function getValue(object, path) {
    return path
        .replace(/\[/g, '.')
        .replace(/\]/g, '')
        .split('.')
        .reduce(function (o, k) {
            return (typeof o === 'string' ? JSON.parse(o) : (o || {}))[k];
        }, object);
}
var object = {"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"},
    path = 'batters.batter[1].id';

console.log(getValue(object, path));



回答2:


The following would do the job using a Regex on each value :

const data = {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batters": {
        "batter": [
            {
                "id": "1001",
                "type": "Regular"
            },
            {
                "id": "1002",
                "type": "Chocolate"
            }
        ]
    },
    "data": "{\"domain\":\"cooking.com\",\"id\":53819390}"
}

function getValue(object, path) {
    return path
        .split('.')
        .reduce(function (o, k) {
            const indexSearch = (new RegExp(/\[([0-9]*)\]/)).exec(k)
            const index = indexSearch ? indexSearch[1] : null
            k = k.replace(/\[[0-9]*\]/, '')
            const sub = (typeof o === 'string' ? JSON.parse(o) : o)[k]
            return index ? sub[index] : sub;
        }, object);
}

console.log(getValue(data, 'batters.batter[1]'))
console.log(getValue(data, 'data.domain'))
console.log(getValue(data, 'batters.batter[1].id'))


来源:https://stackoverflow.com/questions/53841772/getpathvalue-function-for-deep-objects-with-arrays-and-with-packed-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!