Преобразуйте серию ключей объектов JavaScript в массивы, если они содержат числа

У меня есть этот объект:

{
  name: "Gold's Gym Venice",
  "categories[0].alias": "gyms",
  "categories[0].title": "Gyms",
  "categories[1].alias": "healthtrainers",       
  "categories[1].title": "Trainers",
  "location.state": "CA",
  "location.city": "Venice",
  "location.zip_code": "90291",
  "location.display_address[0]": "360 Hampton Dr",
  "location.display_address[1]": "Venice, CA 90291"
}

... и я пытаюсь преобразовать это в это:

{
    name: "Gold's Gym Venice",
    categories: [
        { alias: "gyms", title: "Gyms" },
        { alias: "healthtrainers", title: "Trainers" }
    ],
    location: {
      state: "CA",
      city: "Venice",
      zip_code: "90291",
      display_address: [ "360 Hampton Dr", "Venice, CA 90291" ]
    }
}

Я попробовал оба этих ответов. Каждый из них дает немного разные результаты — второй ближе — но ни один из них не обрабатывает должным образом ключи с числами в квадратных скобках или позициями массива.

Какой лучший способ справиться с этим?

Какой язык вы используете? И насколько изменчива структура?

derpirscher 22.03.2024 15:27

Т.е. насколько глубоко могут быть вложены эти объекты. А что произойдет, например, с клавишей типа foo[0].bar[0].baz (если такое возможно)?

derpirscher 22.03.2024 15:34

@derpirscher JavaScript/ES6+, и его структура не является нестабильной — это было вызвано (надеюсь, единовременным) изменением API, который я использую. Объект может быть настолько глубоким, насколько это необходимо, и пример ключа, который вы дали, будет { foo [ bar [ { baz: ... } ] ] }

Rod Boev 22.03.2024 18:27

Я предлагаю вам использовать такую ​​библиотеку, как lodash _.set(), чтобы установить объект по строковому пути. Использование доверенной библиотеки также помогает защититься от таких вещей, как атаки на загрязнение прототипа, которые могут произойти здесь, если вы не можете доверять своему входному объекту.

Nick Parsons 24.03.2024 08:49

Это тоже сработает. Спасибо. Я не уточнил, что надеялся на самостоятельное решение; по этой причине я выбрал решение, опубликованное @Damzaky. Это не значит, что код lodash полезен для изучения.

Rod Boev 25.03.2024 01:16
Поведение ключевого слова "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) для оценки ваших знаний,...
0
5
148
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я думаю, мы можем использовать метод из этого ответа, вот пример кода для приведенного вами примера:

const deepSet = (obj, path, val) => {
    path = path.replaceAll("[", ".[");
    const keys = path.split(".");

    for (let i = 0; i < keys.length; i++) {
        let currentKey = keys[i];
        let nextKey = keys[i + 1];
        if (currentKey.includes("[")) {
            currentKey = parseInt(currentKey.substring(1, currentKey.length - 1));
        }
        if (nextKey && nextKey.includes("[")) {
            nextKey = parseInt(nextKey.substring(1, nextKey.length - 1));
        }

        if (typeof nextKey !== "undefined") {
            obj[currentKey] = obj[currentKey] ? obj[currentKey] : (isNaN(nextKey) ? {} : []);
        } else {
            obj[currentKey] = val;
        }

        obj = obj[currentKey];
    }
};

const result = {};

const originalObj = {
  'categories[0].alias': 'gyms',
  'categories[0].title': 'Gyms',
  'categories[1].alias': 'healthtrainers',       
  'categories[1].title': 'Trainers',
  'location.display_address[0]': '360 Hampton Dr',
  'location.display_address[1]': 'Venice, CA 90291'
};

for (const [key, value] of Object.entries(originalObj)) {
  deepSet(result, key, value);
}

console.info(result);

Запустив этот код, вы увидите, что он оставляет ключи с именем { '0', '1', ... }, а не массив объектов. Результат очень похож на первый ответ, указанный в вопросе.

Rod Boev 24.03.2024 14:58

@Rod Boev: он оставляет ключи с именами { '0', '1', ... }, а не массив объектов - вы всегда будете получать эти числовые индексы массива при регистрации массивов на консоли. Вот как работают массивы. Таким образом, ответ должен решить вашу проблему.

herrstrietzel 24.03.2024 19:13

@herrstrietzel Мои извинения, я, должно быть, пересекся с решением, над которым работал. Я видел ключи как строки, а не целые числа. Спасибо, @Damzaky!

Rod Boev 25.03.2024 01:12

и если входным данным нельзя доверять, возможно, стоит подумать о замене const result = {}; на const result = Object.create(null); или добавлении Object.freeze(Object.prototype) (отметим, что это глобальное изменение), чтобы избежать атак загрязнения прототипа.

Nick Parsons 25.03.2024 11:29

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