Доступ к глубокому объектному члену встроенного JSON

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

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

Например, он возвращает значение для такого ключа, как «bar», используя в качестве аргумента пути следующее:

'data.abc.foo.bar'

Однако некоторые API-интерфейсы содержат дополнительный строковый JSON в некоторые ключевые значения.

Я ищу усовершенствование вышеупомянутой функции, которое будет обрабатывать этот случай.

Например, собственный сервис WebSocket от Stack:

wss://qa.sockets.stackexchange.com/

возвращает такие строки:

{"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"}

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

'data.bodySummary'

Возможно, входная строка могла бы выглядеть примерно так:

'data/bodySummary'

где солидус (/ косая черта) представляет JSON.parse ().

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

Сегодня проголосовали против ... почему?

Excel Hero 25.12.2018 19:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете проверить, является ли элемент, из которого вы берете свойство, строкой, и выполнить синтаксический анализ. Возвращает значение свойства.

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

var data = {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"};

console.info(getValue(data, 'data.bodySummary'));

ES5

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

var data = {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"};

console.info(getValue(data, 'data.bodySummary'));

Мне это очень нравится. Но мое требование - IE11 и ES5. Можете ли вы переделать это без функции стрелки?

Excel Hero 17.12.2018 21:38

Спасибо. Прекрасно работает.

Excel Hero 17.12.2018 23:28

Есть ли способ улучшить это, чтобы оно работало, когда в JSON есть массивы, а путь включает один или несколько? Дайте мне знать, и я могу начать новый вопрос, если хотите.

Excel Hero 18.12.2018 21:56

Было бы лучше задать новый вопрос с примером данных, которые у вас есть, и более подробным обзором, что вы хотите, поскольку это можно обсудить в разделе комментариев.

Nina Scholz 18.12.2018 22:02

Я только что разместил новый вопрос: stackoverflow.com/q/53841772/3566998

Excel Hero 18.12.2018 23:05

Вот функция, которая принимает объект или строку JSON в качестве первого параметра, строку пути ключа или массив в качестве второго параметра и рекурсивно просматривает объект с помощью пути ключа.

let object = {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"};

function asObject(str) {
    try {
        return JSON.parse(str);
    } catch (e) {
        return str;
    }
}


function valueAtKeyPath(o, path) {
    o = asObject(o);
    if (typeof path === 'string') path = path.split('.');
    
    if (!o || !path.length) return o;
    return valueAtKeyPath(o[path[0]], path.slice(1));
}

console.info(valueAtKeyPath(object, 'action'))
console.info(valueAtKeyPath(object, 'data.id'))

Хорошо, но он не возвращает строковые значения для таких путей, как: valueAtKeyPath (object, 'action')

Excel Hero 17.12.2018 21:43

@ExcelHero - я понимаю, о чем вы. Фиксированный.

danh 17.12.2018 21:57

Спасибо тебе за это. Оно работает. Я также ценю то, что вы обновили его. Я выбираю Nina's, потому что это было первое, и мне нравится, насколько оно лаконично. Мне также нравится, что он возвращает строку вместо объекта для пути: 'данные'

Excel Hero 17.12.2018 23:26

Другие вопросы по теме