Мне нужно создать объект из структуры json. Я не понимаю, как сделать рекурсивную структуру.

Это мой образец структуры json

{
        "dynamic.title": "Lorem Ipsum title",
        "dynamic.main_section.header.title": "Lorem Ipsum main section header title ",
        "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section  body collection first title",
        "dynamic.main_section.body.collection.first.description": "Lorem Ipsum main section  body collection first description",
        "dynamic.main_section.body.collection.first.id": "Lorem Ipsum main section  body collection first id",
        "dynamic.main_section.body.collection.first.child.first.title": "Lorem Ipsum main section  body collection first of first child title ",
        "dynamic.main_section.body.collection.first.child.first.id": "Lorem Ipsum main section  body collection first of first child id ",
        "dynamic.main_section.body.collection.first.child.first.url": "https://loremipsum/1",
        "dynamic.main_section.body.collection.first.child.first.names.first": "John Doe",
        "dynamic.main_section.body.collection.first.child.first.names.second": "Jane Doe",
        "dynamic.main_section.body.collection.second.title": "Lorem Ipsum main section  body collection second title",
        "dynamic.main_section.body.collection.second.description": "Lorem Ipsum main section  body collection second description",
        "dynamic.main_section.body.collection.second.id": "Lorem Ipsum main section  body collection second id",
        "dynamic.main_section.body.collection.second.child.first.title": "Lorem Ipsum main section  body collection second of first child title ",
        "dynamic.main_section.body.collection.second.child.first.id": "Lorem Ipsum main section  body collection second of first child id ",
        "dynamic.main_section.body.collection.second.child.first.url": "https://loremipsum/2",
        "dynamic.main_section.body.collection.second.child.second.title": "Lorem Ipsum main section  body collection second of second child title ",
        "dynamic.main_section.body.collection.second.child.second.id": "Lorem Ipsum main section  body collection second of second child id ",
        "dynamic.main_section.body.collection.second.child.second.url": "https://loremipsum/3"
    }

Мне нужен формат примерно так

{
        "dynamic": {
            "title": "Lorem Ipsum title",
            "main_section": {
                "header": {
                    "title": "Lorem Ipsum main section header title "
                },
                "body": {
                    "collection": [
                        {
                            "title": "Lorem Ipsum main section  body collection first title",
                            "description": "Lorem Ipsum main section  body collection first description",
                            "id": "Lorem Ipsum main section  body collection first id",
                            "child": [
                                {
                                    "title": "Lorem Ipsum main section  body collection first of first child title ",
                                    "id": "Lorem Ipsum main section  body collection first of first child id ",
                                    "url": "https://loremipsum/1",
                                    "names": ["John Doe", "Jane Doe"]
                                }
                            ]
                        },
                        {
                            "title": "Lorem Ipsum main section  body collection second title",
                            "description": "Lorem Ipsum main section  body collection second description",
                            "id": "Lorem Ipsum main section  body collection second id",
                            "child": [
                                {
                                    "title": "Lorem Ipsum main section  body collection second of first child title ",
                                    "id": "Lorem Ipsum main section  body collection second of first child id ",
                                    "url": "https://loremipsum/2"
                                },
                                {
                                    "title": "Lorem Ipsum main section  body collection second of second child title ",
                                    "id": "Lorem Ipsum main section  body collection second of second child id ",
                                    "url": "https://loremipsum/3"
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }

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

Как я мог добиться этого в js?

1
dev 8 Июн 2021 в 21:01

2 ответа

Лучший ответ

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

const
    setValue = (object, path, value) => {
        const
            indices = { first: 0, second: 1 },
            keys = path.replace(new RegExp(Object.keys(indices).join('|'), 'g'), k => indices[k]).split('.'),
            last = keys.pop();

        keys
            .reduce((o, k, i, kk) => o[k] ??= isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}, object)
            [last] = value;
            
        return object;
    },
    data = { "dynamic.title": "Lorem Ipsum title", "dynamic.main_section.header.title": "Lorem Ipsum main section header title ", "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section  body collection first title", "dynamic.main_section.body.collection.first.description": "Lorem Ipsum main section  body collection first description", "dynamic.main_section.body.collection.first.id": "Lorem Ipsum main section  body collection first id", "dynamic.main_section.body.collection.first.child.first.title": "Lorem Ipsum main section  body collection first of first child title ", "dynamic.main_section.body.collection.first.child.first.id": "Lorem Ipsum main section  body collection first of first child id ", "dynamic.main_section.body.collection.first.child.first.url": "https://loremipsum/1", "dynamic.main_section.body.collection.first.child.first.names.first": "John Doe", "dynamic.main_section.body.collection.first.child.first.names.second": "Jane Doe", "dynamic.main_section.body.collection.second.title": "Lorem Ipsum main section  body collection second title", "dynamic.main_section.body.collection.second.description": "Lorem Ipsum main section  body collection second description", "dynamic.main_section.body.collection.second.id": "Lorem Ipsum main section  body collection second id", "dynamic.main_section.body.collection.second.child.first.title": "Lorem Ipsum main section  body collection second of first child title ", "dynamic.main_section.body.collection.second.child.first.id": "Lorem Ipsum main section  body collection second of first child id ", "dynamic.main_section.body.collection.second.child.first.url": "https://loremipsum/2", "dynamic.main_section.body.collection.second.child.second.title": "Lorem Ipsum main section  body collection second of second child title ", "dynamic.main_section.body.collection.second.child.second.id": "Lorem Ipsum main section  body collection second of second child id ", "dynamic.main_section.body.collection.second.child.second.url": "https://loremipsum/3" },
    result = Object
        .entries(data)
        .reduce((r, [k, v]) => setValue(r, k, v), {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2
Nina Scholz 8 Июн 2021 в 18:19

Я покажу вам, как преобразовать данные, чтобы вы могли продолжать их работу и даже автоматизировать, если это необходимо;

let data = {
        "dynamic.title": "Lorem Ipsum title",
        "dynamic.main_section.header.title": "Lorem Ipsum main section header title ",
        "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section  body collection first title"
    }
    
dataTrans = {}
//data["dynamic.title"]
dataTrans.dynamic = {}
dataTrans.dynamic.title = data["dynamic.title"]
//data["dynamic.main_section.header.title"]
dataTrans.dynamic.main_section = {} 
dataTrans.dynamic.main_section.header = {}
dataTrans.dynamic.main_section.header.title = data["dynamic.main_section.header.title"]
dataTrans.dynamic.main_section.body = {} 
dataTrans.dynamic.main_section.body.collection = []
dataTrans.dynamic.main_section.body.collection[0] = {}
dataTrans.dynamic.main_section.body.collection[0].title = data["dynamic.main_section.body.collection.first.title"]

console.log(dataTrans)
0
Hamada 8 Июн 2021 в 18:52