Функция замены JSON.stringify() и пространство имен

Я пытаюсь выделить часть JSON в Javascript, найденную в следующей константе namespace, используя второй параметр JS JSON.strigify() replacer. Поэтому, когда ключ равен пространству имен, он увеличивает индекс в пространстве имен для продвижения. Наконец, я окружаю значение клавишами 0 и Z.

const dataTree = {
    "styles": {
        "elements": {
            "heading": {
                "typography": {
                    "fontFamily": "Volkorn",
                    "fontSize": "16px"
                },
            },
        },
        "typography": {
            "fontFamily": "Vollkorn",
            "fontSize": "16px",
            "lineHeight": "1.7"
        }
    }
}

const namespace = "styles.typography.fontSize".split('.')
let i = 0

const replacer = (k, v) => {
    if (namespace[i] === k){
        i++
        if (i === namespace.length-1){
            if (Object.keys(v).includes(namespace.at(-1))){
                v[0] = 'before' 
                v["Z"] = 'after' 
                return v
            }
        }
    }
    if (v["Z"]) {
        delete v["Z"]
        delete v[0]
    } 
    return v
}
const strV = JSON.stringify(dataTree, replacer, 2)

Проблема не в том, чтобы идти по правильному пути. В приведенном выше примере он идет к styles.elements.heading.typography.fontSize вместо styles.typography.fontSize.

Есть идеи ?

Вы сказали, что хотите сделать это в «JSON», но то, что вы показали, является объектом JavaScript. JSON — это текстовая запись для обмена данными. (Подробнее здесь.) Если вы имеете дело с исходным кодом JavaScript, а не со строкой, вы не имеете дело с JSON. Вы пытаетесь сделать это в объекте JavaScript, который затем сериализуете в JSON? Потому что это сложно (возможно, невозможно) сделать с помощью функции-заменителя, но довольно легко сделать это до преобразования в JSON.

T.J. Crowder 15.11.2022 18:27

Также покажите ожидаемый результат.

T.J. Crowder 15.11.2022 18:35

dataTree — это объект JS, да. strV — это версия строки JSON, включающая в себя некоторые специальные ключи для окружения значений, которые я хотел бы выделить.

Romain Guillaume 15.11.2022 18:57

Я ожидал, что метод stringify будет иметь более точный контроль над функцией замены, которая предоставляет только ключ и значение, но не путь или пространство имен, чтобы точно идентифицировать обрабатываемую часть объекта. Если вы запустите его, вы получите результат, аналогичный тому, что я ожидаю. Проблема в том, что он изменяет styles.elements.heading.typography.fontSize вместо styles.typography.fontSize. Наконец, я собираюсь внести эти изменения, чтобы сделать это до преобразования в JSON, так как нет возможности проверить путь, по которому находится функция-заменитель.

Romain Guillaume 15.11.2022 19:05
Поведение ключевого слова "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
4
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Если вы используете заменитель, он вызывается рекурсивно для измененного объекта, который возвращает заменитель.

Если заменитель вставляет в дерево новые свойства, это затрудняет отслеживание позиции в дереве, над которой работает текущий вызов заменителя.

Вместо этого вы можете сделать это с объектами:

const dataTree = {"styles":{"elements":{"heading":{"typography":{"fontFamily":"Volkorn","fontSize":"16px"}}},"typography":{"fontFamily":"Vollkorn","fontSize":"16px","lineHeight":"1.7"}}};

const namespace = 'styles.typography.fontSize'.split('.');

const replaceAtLocation = (tree, [p,...rest], replacer) => rest.length ?
  Object.fromEntries(Object.entries(tree).map(([k,v])=>k===p ?
    [k,replaceAtLocation(v, rest, replacer)] : [k,v])) : replacer(tree);

const result = replaceAtLocation(dataTree,namespace,tree=>Object.fromEntries(
  Object.entries(tree).flatMap(([k,v])=>k===[...namespace].pop()?
    [['A','before'],[k,v],['Z','after']]:[[k,v]])));

console.info(JSON.stringify(result, null, 2));

Обратите внимание, что я заменил «0» на «A», так как «0» всегда будет располагаться первым свойством в объекте, а не непосредственно перед желаемым свойством.

Что ж, ваш ответ полностью рабочий. Тем не менее, это очень компактно, мне потребуется некоторое время, чтобы понять все это. Спасибо!

Romain Guillaume 15.11.2022 20:59

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