Функция getPathValue () для глубоких объектов с массивами и с упакованным JSON - PullRequest
0 голосов
/ 19 декабря 2018

Для справки, пожалуйста, обратитесь к этому вопросу: Доступ к глубокому объекту-члену встраиваемого JSON

Предлагаемые там решения очень хорошо работали с упакованным JSON, содержащимся в ключевых значениях.

Однако они не обрабатывают ситуацию, когда JSON имеет массивы.

Исходная функция, на которую я ссылался в другом вопросе, обрабатывает массивы DID, но она не будет обрабатывать упакованный JSON.

Это оригинальная функция:

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

и это ответ на первый вопрос:

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

Опять же, оба работают хорошо, но ни один не предлагает весь пакет.

Мне нужно решение, которое будет выполнять обе задачи, и оно должно работать в ES5 IE11.

Вот пример возвращаемой строки JSON API:

{"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}"}

Я бы хотел бытьвозможность запрашивать значения с помощью строки пути, например:

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

или

value = getPathValue(obj, 'type');

или

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

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Следующее будет выполнять работу с использованием регулярных выражений для каждого значения:

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'))
0 голосов
/ 19 декабря 2018

Вы можете заменить скобки и взять оставшиеся значения в качестве ключей.Внутри сокращения вы можете использовать объект по умолчанию для не заданных объектов.

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));
...